/*
 * @Author       : Bing Chen chenbing@iocharger.com
 * @Date         : 2024-05-31 11:32:16
 * @LastEditors  : liubangyi liubangliuyi@163.com
 * @LastEditTime : 2025-03-17 15:46:26
 * @FilePath     : /openchaoji-corelib/secc/gbt27930/OpenChaoJi_secc_gbt27930_b.c
 * @Description  :
 *
 * Copyright (c) 2025 OpenChaoJi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the icense for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "../include/OpenChaoJi_secc.h"

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)

struct OpenChaoJi_secc_gbt27930_b_data
{
    /* -------------- IDLE 模块 特来电 -------------- */
    struct {
        int dummy;
    } idle;

    /* -------------- Trigger 模块 特来电 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer Tc;
    } trigger;

    /* -------------- 功能协商 模块 嘉盛 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer Tc;

        struct OpenChaoJi_gbt27930_b_msg_func_support_secc func_support_secc;

        struct OpenChaoJi_gbt27930_b_msg_func_support_evcc func_support_evcc;
        int func_support_evcc_ok;

    } func_nego;

    /* -------------- 参数配置 模块 嘉盛 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer Tc;

        struct OpenChaoJi_gbt27930_b_msg_param_config_secc param_config_secc;

        struct OpenChaoJi_gbt27930_b_msg_param_config_evcc param_config_evcc;
        int param_config_evcc_ok;

    } param_config;
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_AUTH == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_RFID == CONFIG_YES)

    /* -------------- 授权(RFID) 模块 鲁软 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer Tc;

        struct OpenChaoJi_os_soft_timer T1;

        struct OpenChaoJi_os_soft_timer T2;

        struct OpenChaoJi_gbt27930_b_msg_auth_rfid_param_secc rfid_param_secc;

        struct OpenChaoJi_gbt27930_b_msg_auth_rfid_wait_evcc  rfid_wait_evcc;

        struct OpenChaoJi_gbt27930_b_msg_auth_rfid_result_secc rfid_result_secc;
        int rfid_wait_evcc_ok; //车辆是否同意等待报文

        enum secc_app_auth_status app_auth_status_rfid;

    } auth_rfid;

    #endif
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_EVIN == CONFIG_YES)

    /* -------------- 授权(EVIN) 模块 鲁软 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer Tc;

        struct OpenChaoJi_gbt27930_b_msg_auth_evin_req_secc evin_req_secc;

        struct OpenChaoJi_gbt27930_b_msg_auth_evin_param_evcc evin_param_evcc;

        struct OpenChaoJi_gbt27930_b_msg_auth_evin_result_secc evin_result_secc;
        int evin_param_evcc_ok;//车辆鉴权参数

        enum secc_app_auth_status app_auth_status_evin;

    } auth_evin;
    #endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_RESERVE == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_RESERVE_EVCC == CONFIG_YES)

    /* -------------- 预约 模块 (暂空) -------------- */
    #endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SELFCHECK == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SELFCHECK_GENERAL == CONFIG_YES)

    /* -------------- 系统自检 模块 领充 -------------- */
	/*系统自检内容定义*/
	struct {
        struct OpenChaoJi_os_soft_timer Tc;

		struct OpenChaoJi_os_soft_timer T1;

        struct OpenChaoJi_gbt27930_b_msg_selfcheck_status_secc selfcheck_status_secc;

        struct OpenChaoJi_gbt27930_b_msg_selfcheck_result_secc selfcheck_result_secc;

    } self_check;
    #endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SUPPLY == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SUPPLY_BASIC == CONFIG_YES)
    /* -------------- 供电模式 模块 (暂空) -------------- */
    #endif
#endif
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_CHARGING == CONFIG_YES)

    /* -------------- 预充及能量传输 模块 鲁软 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer Tc;

        struct OpenChaoJi_os_soft_timer T1;

        struct OpenChaoJi_os_soft_timer T2;

        struct OpenChaoJi_gbt27930_b_msg_charging_ready_secc charging_ready_secc;

        struct OpenChaoJi_gbt27930_b_msg_charging_ready_evcc charging_ready_evcc;
        int charging_ready_evcc_ok;//接收车辆就绪状态报文

        struct OpenChaoJi_gbt27930_b_msg_charging_requirement_evcc charging_requirement_evcc;
        int charging_requirement_evcc_ok;//接收"车辆充电需求"报文

        struct OpenChaoJi_gbt27930_b_msg_charging_info_basic_evcc charging_info_basic_evcc;
        int charging_info_basic_evcc_ok;//接收"车辆充电基本信息"报文

        struct OpenChaoJi_gbt27930_b_msg_charging_info_battery_evcc charging_info_battery_evcc;
        int charging_info_battery_evcc_ok;//接收"车辆充电电池基本信息"报文

        struct OpenChaoJi_gbt27930_b_msg_charging_ability_secc charging_ability_secc;

        struct OpenChaoJi_gbt27930_b_msg_charging_pause_secc charging_pause_secc;

        struct OpenChaoJi_gbt27930_b_msg_charging_pause_evcc charging_pause_evcc;
        int charging_pause_evcc_ok;//接收"车辆暂停充电通知"报文

        struct OpenChaoJi_secc_hal_samp  charging_secc_hal_samp;
        unsigned char charging_precharge_status;    //预充状态  0x00 电池电压在正常范围  0x01 车辆供电回路电压正常 0x02 C1 C2闭合

        unsigned int volt_power_module;     // 当前设置给模块的电压电流
        unsigned int curr_power_module;

    } charging;
    #endif
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_DISCHARGING == CONFIG_YES)
    /* -------------- 预充及能量传输(放电) 模块 暂空 -------------- */
    #endif

    /* -------------- 服务统计停止中 鲁软 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer State_Tc;//阶段确认定时

        struct OpenChaoJi_os_soft_timer Normal_Tc;
        struct OpenChaoJi_os_soft_timer Normal_T1;
        struct OpenChaoJi_os_soft_timer Normal_T2;
        struct OpenChaoJi_os_soft_timer Normal_T3;
        struct OpenChaoJi_os_soft_timer Normal_T4;

        struct OpenChaoJi_os_soft_timer Fault_Tc;
        struct OpenChaoJi_os_soft_timer Fault_T1;
        struct OpenChaoJi_os_soft_timer Fault_T2;
        struct OpenChaoJi_os_soft_timer Fault_T3;
        struct OpenChaoJi_os_soft_timer Fault_T4;

        struct OpenChaoJi_os_soft_timer Emrge_Tc;
        struct OpenChaoJi_os_soft_timer Emrge_T1;
        struct OpenChaoJi_os_soft_timer Emrge_T2;
        struct OpenChaoJi_os_soft_timer Emrge_T3;
        struct OpenChaoJi_os_soft_timer Emrge_T4;

        int statistics_stoping_emergency_secc_state;//紧急停机状态 0x00 0x01 0x02 0x03 0x04 0x05
        int statistics_stoping_fault_secc_state;//故障停机状态 0x00 0x01 0x02 0x03 0x04 0x05
        int statistics_stoping_normol_secc_state;//正常停机状态 0x00 0x01 0x02 0x03 0x04 0x05

    } statistics_stoping;

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_STATISTICS == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_STATISTICS == CONFIG_YES)

    /* -------------- 服务统计 模块 长园 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer Tc;

        struct OpenChaoJi_gbt27930_b_msg_statistics_secc statistics_secc;

        struct OpenChaoJi_gbt27930_b_msg_statistics_evcc statistics_evcc;
        int statistics_evcc_ok;

    } statistics;
    #endif
#endif

    /* -------------- END 模块 星星 -------------- */

    /* -------------- FAULT 模块 星星 -------------- */

    /* -------------- 通用数据 鲁软 -------------- */
    // 充电机阶段信息报文
    struct OpenChaoJi_gbt27930_b_msg_phase_info_secc phase_info_secc;

    struct OpenChaoJi_gbt27930_b_msg_phase_ack_evcc phase_ack_evcc;
    int phase_ack_evcc_ok;

    struct OpenChaoJi_gbt27930_b_msg_stop_info_secc stop_info_secc;
    int stop_info_secc_sent;//0未发送 1已发送中止报文

    struct OpenChaoJi_gbt27930_b_msg_stop_info_evcc stop_info_evcc;
    int stop_info_evcc_ok;

	// 充电机直流供电回路接触器状态报文
	struct OpenChaoJi_gbt27930_b_msg_relay_status_secc relay_status_secc;
    unsigned char hal_relay_status_secc;
    struct OpenChaoJi_os_soft_timer relay_status_secc_T1;

	struct OpenChaoJi_gbt27930_b_msg_relay_status_evcc relay_status_evcc;
    int relay_status_evcc_ok;

    // 车辆电子锁状态报文, B类系统由车端负责, 桩端无电子锁状态报文
	struct OpenChaoJi_gbt27930_b_msg_latching_status_evcc latchging_status_evcc;
	int latchging_status_evcc_ok;

    struct OpenChaoJi_secc_app_start_parameter app_start_parameter;

    /* -------------- 日志专用 -------------- */
    struct {
        struct OpenChaoJi_gbt27930_b_msg_func_support_secc func_support_secc;
        // struct OpenChaoJi_gbt27930_b_msg_func_support_evcc func_support_evcc;
        struct OpenChaoJi_gbt27930_b_msg_param_config_secc param_config_secc;
        // struct OpenChaoJi_gbt27930_b_msg_param_config_evcc param_config_evcc;
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_AUTH == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_RFID == CONFIG_YES)
        struct OpenChaoJi_gbt27930_b_msg_auth_rfid_param_secc auth_rfid_param_secc;
        struct OpenChaoJi_gbt27930_b_msg_auth_rfid_result_secc auth_rfid_result_secc;
        // struct OpenChaoJi_gbt27930_b_msg_auth_rfid_wait_evcc auth_rfid_wait_evcc;
    #endif
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_EVIN == CONFIG_YES)
        struct OpenChaoJi_gbt27930_b_msg_auth_evin_req_secc auth_evin_req_secc;
        // struct OpenChaoJi_gbt27930_b_msg_auth_evin_param_evcc auth_evin_param_evcc;
        struct OpenChaoJi_gbt27930_b_msg_auth_evin_result_secc auth_evin_result_secc;
    #endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_RESERVE == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_RESERVE_EVCC == CONFIG_YES)
        struct OpenChaoJi_gbt27930_b_msg_reserve_info_secc reserve_info_secc;
        struct OpenChaoJi_gbt27930_b_msg_reserve_confirm_secc reserve_confirm_secc;
        // struct OpenChaoJi_gbt27930_b_msg_reserve_info_evcc reserve_info_evcc;
        // struct OpenChaoJi_gbt27930_b_msg_reserve_nego_evcc reserve_nego_evcc;
    #endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SELFCHECK == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SELFCHECK_GENERAL == CONFIG_YES)
        struct OpenChaoJi_gbt27930_b_msg_selfcheck_status_secc selfcheck_status_secc;
        struct OpenChaoJi_gbt27930_b_msg_selfcheck_result_secc selfcheck_result_secc;
    #endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SUPPLY == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SUPPLY_BASIC == CONFIG_YES)
        struct OpenChaoJi_gbt27930_b_msg_supply_status_secc supply_status_secc;
        // struct OpenChaoJi_gbt27930_b_msg_supply_status_evcc supply_status_evcc;
        // struct OpenChaoJi_gbt27930_b_msg_supply_requirement_evcc supply_requirement_evcc;
        struct OpenChaoJi_gbt27930_b_msg_supply_ability_secc supply_ability_secc;
        // struct OpenChaoJi_gbt27930_b_msg_supply_finish_evcc supply_finish_evcc;
    #endif
#endif
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_CHARGING == CONFIG_YES)
        struct OpenChaoJi_gbt27930_b_msg_charging_ready_secc charging_ready_secc;
        // struct OpenChaoJi_gbt27930_b_msg_charging_ready_evcc charging_ready_evcc;
        // struct OpenChaoJi_gbt27930_b_msg_charging_requirement_evcc charging_requirement_evcc;
        // struct OpenChaoJi_gbt27930_b_msg_charging_info_basic_evcc charging_info_basic_evcc;
        // struct OpenChaoJi_gbt27930_b_msg_charging_info_battery_evcc charging_info_battery_evcc;
        struct OpenChaoJi_gbt27930_b_msg_charging_ability_secc charging_ability_secc;
        struct OpenChaoJi_gbt27930_b_msg_charging_pause_secc charging_pause_secc;
        // struct OpenChaoJi_gbt27930_b_msg_charging_pause_evcc charging_pause_evcc;
    #endif
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_DISCHARGING == CONFIG_YES)
        struct OpenChaoJi_gbt27930_b_msg_discharging_readiness_info_secc discharging_readiness_info_secc;
        // struct OpenChaoJi_gbt27930_b_msg_discharging_readiness_info_evcc discharging_readiness_info_evcc;
        // struct OpenChaoJi_gbt27930_b_msg_discharging_status_info_evcc discharging_status_info_evcc;
        // struct OpenChaoJi_gbt27930_b_msg_discharging_basic_info_evcc discharging_basic_info_evcc;
        struct OpenChaoJi_gbt27930_b_msg_discharging_output_capability_secc discharging_output_capability_secc;
        struct OpenChaoJi_gbt27930_b_msg_discharging_status_secc discharging_status_secc;
    #endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_STATISTICS == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_STATISTICS == CONFIG_YES)
        struct OpenChaoJi_gbt27930_b_msg_statistics_secc statistics_secc;
        // struct OpenChaoJi_gbt27930_b_msg_statistics_evcc statistics_evcc;
    #endif
#endif
        struct OpenChaoJi_gbt27930_b_msg_phase_info_secc phase_info_secc;
        // struct OpenChaoJi_gbt27930_b_msg_phase_ack_evcc phase_ack_evcc;
        struct OpenChaoJi_gbt27930_b_msg_relay_status_secc relay_status_secc;
        // struct OpenChaoJi_gbt27930_b_msg_relay_status_evcc relay_status_evcc;
        // struct OpenChaoJi_gbt27930_b_msg_latching_status_evcc latching_status_evcc;
        struct OpenChaoJi_gbt27930_b_msg_stop_info_secc stop_info_secc;
        // struct OpenChaoJi_gbt27930_b_msg_stop_info_evcc stop_info_evcc;
    } log_msg;
};


bool s_gbt_b_public_debug_enable = false;
void OpenChaoJi_debug_set_log_module_gbt_b_public(bool enable)
{
    s_gbt_b_public_debug_enable = enable;
}

/* -------------- 通用功能 鲁软 -------------- */
static int OpenChaoJi_gbt27930_b_secc_parse_data(struct OpenChaoJi_secc_context * context, struct OpenChaoJi_utility_data_buff_recv_data * recv_data);

/**
 * @brief: 停止系统定时器
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 * @return {*}
 */
static void OpenChaoJi_gbt27930_b_secc_running_data_timer_reset(struct OpenChaoJi_secc_context * context)
{
    LOG_NOTICE("[%d]STOP ALL TIMER", context->tag);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->trigger.Tc);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->func_nego.Tc);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->param_config.Tc);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.Tc);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.T1);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.T2);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_evin.Tc);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->self_check.Tc);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->self_check.T1);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.Tc);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T1);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.State_Tc);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_Tc);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T1);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T2);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T3);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T4);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_Tc);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T1);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T2);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T3);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T4);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_Tc);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T1);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T2);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T3);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T4);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics.Tc);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->relay_status_secc_T1);

    return;
}

/**
 * @brief: 重置系统运行数据
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 * @return {*}
 */
static void OpenChaoJi_gbt27930_b_secc_running_data_reset(struct OpenChaoJi_secc_context * context)
{
    LOG_STATUS_CHANGE("[%d]RESET RUNNING DATA", context->tag);

	memset(context->running_data.b, 0x00, sizeof(struct OpenChaoJi_secc_gbt27930_b_data));
    context->running_data.b->func_nego.func_support_secc.pid = OPENCHAOJI_GBT27930_B_PGI_FUNC_NEGO_SECC;

    context->running_data.b->param_config.param_config_secc.pid = OPENCHAOJI_GBT27930_B_PGI_PARAM_CONFIG_SECC;

	context->running_data.b->auth_rfid.rfid_param_secc.pid = OPENCHAOJI_GBT27930_B_PGI_AUTH_RFID_PARAM_SECC;
    context->running_data.b->auth_rfid.rfid_result_secc.pid = OPENCHAOJI_GBT27930_B_PGI_AUTH_RFID_RESULT_SECC;

    context->running_data.b->auth_evin.evin_req_secc.pid = OPENCHAOJI_GBT27930_B_PGI_AUTH_EVIN_REQ_SECC;
    context->running_data.b->auth_evin.evin_result_secc.pid = OPENCHAOJI_GBT27930_B_PGI_AUTH_EVIN_RESULT_SECC;

    context->running_data.b->self_check.selfcheck_status_secc.pid = OPENCHAOJI_GBT27930_B_PGI_SELFCHECK_STATUS_SECC;
    context->running_data.b->self_check.selfcheck_result_secc.pid = OPENCHAOJI_GBT27930_B_PGI_SELFCHECK_RESULT_SECC;

    context->running_data.b->charging.charging_ready_secc.pid = OPENCHAOJI_GBT27930_B_PGI_CHARGING_READY_SECC;//参数组标识
    context->running_data.b->charging.charging_ability_secc.pid = OPENCHAOJI_GBT27930_B_PGI_CHARGING_ABILITY_SECC;
    context->running_data.b->charging.charging_pause_secc.pid = OPENCHAOJI_GBT27930_B_PGI_CHARGING_PAUSE_SECC;

    context->running_data.b->statistics.statistics_secc.pid = OPENCHAOJI_GBT27930_B_PGI_STATISTICS_SECC;

    context->running_data.b->phase_info_secc.pid = OPENCHAOJI_GBT27930_B_PGI_PUBLIC_PHASE_INFO_SECC;
    context->running_data.b->stop_info_secc.pid = OPENCHAOJI_GBT27930_B_PGI_PUBLIC_STOP_INFO_SECC;
    context->running_data.b->relay_status_secc.pid = OPENCHAOJI_GBT27930_B_PGI_PUBLIC_RELAY_STATUS_SECC;

    OpenChaoJi_gbt27930_b_secc_running_data_timer_reset(context);

    return;
}

/**
 * @brief: 系统复位
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 * @return {*}
 */
static void OpenChaoJi_gbt27930_b_secc_reset_to_default(struct OpenChaoJi_secc_context * context)
{
    LOG_STATUS_CHANGE("[%d] RESET TO DEFAULT", context->tag);

    OpenChaoJi_secc_utility_session_reset(context->context_session);
    OpenChaoJi_secc_utility_pilot_reset(context->context_pilot);

	OpenChaoJi_gbt27930_b_secc_running_data_reset(context);
}

/**
 * @brief: 根据不同的消息类型更新系统上下文中的运行数据
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 * @param {OpenChaoJi_gbt27930_b_msg *} msg 包含消息数据的结构体指针
 * @return {true: 消息处理成功 false: 消息内容与当前记录一致无需更新}
 */
static bool OpenChaoJi_gbt27930_b_secc_log_msg_set(struct OpenChaoJi_secc_context * context, struct OpenChaoJi_gbt27930_b_msg * msg)
{
    switch (msg->pid)
    {
    case OPENCHAOJI_GBT27930_B_PGI_FUNC_NEGO_SECC:
        if (memcmp(&context->running_data.b->log_msg.func_support_secc, &msg->msg.func_support_secc, sizeof(msg->msg.func_support_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.func_support_secc, &msg->msg.func_support_secc, sizeof(msg->msg.func_support_secc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_PARAM_CONFIG_SECC:
        if (memcmp(&context->running_data.b->log_msg.param_config_secc, &msg->msg.param_config_secc, sizeof(msg->msg.param_config_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.param_config_secc, &msg->msg.param_config_secc, sizeof(msg->msg.param_config_secc));
            return true;
        }
        return false;
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_AUTH == CONFIG_YES)

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_RFID == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_AUTH_RFID_PARAM_SECC:
        if (memcmp(&context->running_data.b->log_msg.auth_rfid_param_secc, &msg->msg.auth_rfid_param_secc, sizeof(msg->msg.auth_rfid_param_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.auth_rfid_param_secc, &msg->msg.auth_rfid_param_secc, sizeof(msg->msg.auth_rfid_param_secc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_AUTH_RFID_RESULT_SECC:
        if (memcmp(&context->running_data.b->log_msg.auth_rfid_result_secc, &msg->msg.auth_rfid_result_secc, sizeof(msg->msg.auth_rfid_result_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.auth_rfid_result_secc, &msg->msg.auth_rfid_result_secc, sizeof(msg->msg.auth_rfid_result_secc));
            return true;
        }
        return false;
    #endif

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_EVIN == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_AUTH_EVIN_REQ_SECC:
        if (memcmp(&context->running_data.b->log_msg.auth_evin_req_secc, &msg->msg.auth_evin_req_secc, sizeof(msg->msg.auth_evin_req_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.auth_evin_req_secc, &msg->msg.auth_evin_req_secc, sizeof(msg->msg.auth_evin_req_secc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_AUTH_EVIN_RESULT_SECC:
        if (memcmp(&context->running_data.b->log_msg.auth_evin_result_secc, &msg->msg.auth_evin_result_secc, sizeof(msg->msg.auth_evin_result_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.auth_evin_result_secc, &msg->msg.auth_evin_result_secc, sizeof(msg->msg.auth_evin_result_secc));
            return true;
        }
        return false;
    #endif

#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_RESERVE == CONFIG_YES)

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_RESERVE_EVCC == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_RESERVE_INFO_SECC:
        if (memcmp(&context->running_data.b->log_msg.reserve_info_secc, &msg->msg.reserve_info_secc, sizeof(msg->msg.reserve_info_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.reserve_info_secc, &msg->msg.reserve_info_secc, sizeof(msg->msg.reserve_info_secc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_RESERVE_CONFIRM_SECC:
        if (memcmp(&context->running_data.b->log_msg.reserve_confirm_secc, &msg->msg.reserve_confirm_secc, sizeof(msg->msg.reserve_confirm_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.reserve_confirm_secc, &msg->msg.reserve_confirm_secc, sizeof(msg->msg.reserve_confirm_secc));
            return true;
        }
        return false;
    #endif

#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SELFCHECK == CONFIG_YES)

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SELFCHECK_GENERAL == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_SELFCHECK_STATUS_SECC:
        if (memcmp(&context->running_data.b->log_msg.selfcheck_status_secc, &msg->msg.selfcheck_status_secc, sizeof(msg->msg.selfcheck_status_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.selfcheck_status_secc, &msg->msg.selfcheck_status_secc, sizeof(msg->msg.selfcheck_status_secc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_SELFCHECK_RESULT_SECC:
        if (memcmp(&context->running_data.b->log_msg.selfcheck_result_secc, &msg->msg.selfcheck_result_secc, sizeof(msg->msg.selfcheck_result_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.selfcheck_result_secc, &msg->msg.selfcheck_result_secc, sizeof(msg->msg.selfcheck_result_secc));
            return true;
        }
        return false;
    #endif

#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SUPPLY == CONFIG_YES)

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SUPPLY_BASIC == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_SUPPLY_STATUS_SECC:
        if (memcmp(&context->running_data.b->log_msg.supply_status_secc, &msg->msg.supply_status_secc, sizeof(msg->msg.supply_status_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.supply_status_secc, &msg->msg.supply_status_secc, sizeof(msg->msg.supply_status_secc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_SUPPLY_ABILITY_SECC:
        if (memcmp(&context->running_data.b->log_msg.supply_ability_secc, &msg->msg.supply_ability_secc, sizeof(msg->msg.supply_ability_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.supply_ability_secc, &msg->msg.supply_ability_secc, sizeof(msg->msg.supply_ability_secc));
            return true;
        }
        return false;
    #endif

#endif

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_CHARGING == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_READY_SECC:
        if (memcmp(&context->running_data.b->log_msg.charging_ready_secc, &msg->msg.charging_ready_secc, sizeof(msg->msg.charging_ready_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.charging_ready_secc, &msg->msg.charging_ready_secc, sizeof(msg->msg.charging_ready_secc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_ABILITY_SECC:
        if (memcmp(&context->running_data.b->log_msg.charging_ability_secc, &msg->msg.charging_ability_secc, sizeof(msg->msg.charging_ability_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.charging_ability_secc, &msg->msg.charging_ability_secc, sizeof(msg->msg.charging_ability_secc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_PAUSE_SECC:
        if (memcmp(&context->running_data.b->log_msg.charging_pause_secc, &msg->msg.charging_pause_secc, sizeof(msg->msg.charging_pause_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.charging_pause_secc, &msg->msg.charging_pause_secc, sizeof(msg->msg.charging_pause_secc));
            return true;
        }
        return false;
    #endif

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_DISCHARGING == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_DISCHARGING_READY_SECC:
        if (memcmp(&context->running_data.b->log_msg.discharging_readiness_info_secc, &msg->msg.discharging_readiness_info_secc, sizeof(msg->msg.discharging_readiness_info_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.discharging_readiness_info_secc, &msg->msg.discharging_readiness_info_secc, sizeof(msg->msg.discharging_readiness_info_secc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_DISCHARGING_ABILITY_SECC:
        if (memcmp(&context->running_data.b->log_msg.discharging_output_capability_secc, &msg->msg.discharging_output_capability_secc, sizeof(msg->msg.discharging_output_capability_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.discharging_output_capability_secc, &msg->msg.discharging_output_capability_secc, sizeof(msg->msg.discharging_output_capability_secc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_DISCHARGING_STATUS_SECC:
        if (memcmp(&context->running_data.b->log_msg.discharging_status_secc, &msg->msg.discharging_status_secc, sizeof(msg->msg.discharging_status_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.discharging_status_secc, &msg->msg.discharging_status_secc, sizeof(msg->msg.discharging_status_secc));
            return true;
        }
        return false;
    #endif


#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_STATISTICS == CONFIG_YES)

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_STATISTICS == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_STATISTICS_SECC:
        if (memcmp(&context->running_data.b->log_msg.statistics_secc, &msg->msg.statistics_secc, sizeof(msg->msg.statistics_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.statistics_secc, &msg->msg.statistics_secc, sizeof(msg->msg.statistics_secc));
            return true;
        }
        return false;
    #endif

#endif
    case OPENCHAOJI_GBT27930_B_PGI_PUBLIC_PHASE_INFO_SECC:
        if (memcmp(&context->running_data.b->log_msg.phase_info_secc, &msg->msg.phase_info_secc, sizeof(msg->msg.phase_info_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.phase_info_secc, &msg->msg.phase_info_secc, sizeof(msg->msg.phase_info_secc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_PUBLIC_RELAY_STATUS_SECC:
        if (memcmp(&context->running_data.b->log_msg.relay_status_secc, &msg->msg.relay_status_secc, sizeof(msg->msg.relay_status_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.relay_status_secc, &msg->msg.relay_status_secc, sizeof(msg->msg.relay_status_secc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_PUBLIC_STOP_INFO_SECC:
        if (memcmp(&context->running_data.b->log_msg.stop_info_secc, &msg->msg.stop_info_secc, sizeof(msg->msg.stop_info_secc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.stop_info_secc, &msg->msg.stop_info_secc, sizeof(msg->msg.stop_info_secc));
            return true;
        }
        return false;

    default: return false;
    }
}

/**
 * @brief: 通用报文发送
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 * @param {uint32_t} all 标签信息
 * @param {uint8_t *} data 待发送的数据
 * @param {uint16_t} data_len 数据长度
* @return {int} 返回值 发送结果是否等于0
 */
static int OpenChaoJi_gbt27930_b_secc_send_normal(struct OpenChaoJi_secc_context * context, uint32_t all, uint8_t *data ,uint16_t data_len)
{
    struct OpenChaoJi_utility_data_buff_send_data send_data;
    send_data.tag.all = all;
    send_data.cnt = SEND_NORMAL_CNT_MACRO;
    send_data.interval_ms = SEND_NORMAL_INTERVAL_MS_MACRO;

    struct OpenChaoJi_gbt27930_b_msg msg;
    msg.pid = OPENCHAOJI_GBT27930_B_PID_FROM_TAG(all);
    memcpy(&msg.msg, data, data_len);

 #if 0
    send_data.send_data.src_free = SEND_NORMAL_SRC_FREE_MACRO;
    send_data.send_data.data = data;
    send_data.send_data.len = data_len;
#else
    int dynamic_data_len = 0;
    unsigned char * dynamic_data = OpenChaoJi_gbt27930_b_msg_encode_data(&msg, &dynamic_data_len);
    if (dynamic_data == NULL)
    {
        return 0;
    }
    send_data.send_data.src_free = 0;
    send_data.send_data.data = dynamic_data;
    send_data.send_data.len = dynamic_data_len;
#endif

    bool changed = OpenChaoJi_gbt27930_b_secc_log_msg_set(context, &msg);

    // 发送数据发生变化必须打出完整报文, 打印级别是INFO则把所有报文打印出来
    if ((changed) || ((OpenChaoJi_debug_get_log_level() & DBGL_INFO) != 0))
    {
        if (msg.pid == OPENCHAOJI_GBT27930_B_PGI_PUBLIC_RELAY_STATUS_SECC)     // RELAY 周期性报文, 即使INFO级别也不打印, 只变化才打印
        {
            if (!changed && !s_gbt_b_public_debug_enable)
            {
                goto SEND_DATA;
            }
        }

        OpenChaoJi_gbt27930_b_msg_log(&msg);
        if ((OpenChaoJi_debug_get_log_level() & DBGL_INFO) != 0)
        {
            LOG_DATA_CHANGE("->[%02X][%d]", msg.pid, send_data.send_data.len);
            LOG_DATA_BUFF_CHANGE(send_data.send_data.data, send_data.send_data.len);
        }
    }

SEND_DATA:
    return OpenChaoJi_secc_utility_session_data_write(context->context_session, &send_data);
}

/**
 * @brief: 充电机阶段信息发送
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 * @param {uint8_t} fc_type fc
 * @param {uint8_t} fdc_type fdc
 * @return {*}
 */
static void OpenChaoJi_gbt27930_b_secc_phase_info_send(struct OpenChaoJi_secc_context * context, uint8_t fc_type, uint8_t fdc_type)
{
    context->running_data.b->phase_ack_evcc_ok = 0;         // 置为0 等待对方应答

    context->running_data.b->phase_info_secc.pid = OPENCHAOJI_GBT27930_B_PGI_PUBLIC_PHASE_INFO_SECC;
    context->running_data.b->phase_info_secc.fc_type = fc_type;
    context->running_data.b->phase_info_secc.fdc_type = fdc_type;

    OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_PHASE_INFO_SECC,  (uint8_t *)(&context->running_data.b->phase_info_secc), sizeof(context->running_data.b->phase_info_secc));

    return;
}

/**
 * @brief: 充电机中止报文发送
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 * @param {uint8_t} end_code 停机码
 * @param {uint8_t} end_Reason 停机原因
 * @return {*}
 */
static void OpenChaoJi_gbt27930_b_secc_stop_info_send(struct OpenChaoJi_secc_context * context, uint8_t end_code, uint8_t end_Reason)
{
    if (end_code != 0)
    {
        memset(&context->running_data.b->stop_info_secc, 0, sizeof(context->running_data.b->stop_info_secc));

        context->running_data.b->stop_info_secc.pid = OPENCHAOJI_GBT27930_B_PGI_PUBLIC_STOP_INFO_SECC;
        context->running_data.b->stop_info_secc.end_code = end_code;
        if (end_Reason != 0)
        {
            context->running_data.b->stop_info_secc.end_Reason = end_Reason;
        }
        // TODO: 故障码目前未定义
        // context->running_data.b->stop_info_secc.fault_code  = (uint8_t *)&fault_code;

        OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_STOP_INFO_SECC, (uint8_t *)(&context->running_data.b->stop_info_secc), sizeof(context->running_data.b->stop_info_secc));

        context->running_data.b->stop_info_secc_sent = 1;
    }

    return;
}

/**
 * @brief: 充电机接触器状态信息发送
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 * @param {unsigned char} hal_relay_status 接触器状态
 * @return {*}
 */
static void OpenChaoJi_gbt27930_b_secc_relay_info_send(struct OpenChaoJi_secc_context * context, unsigned char hal_relay_status)
{
    memset(&context->running_data.b->relay_status_secc, 0, sizeof(context->running_data.b->relay_status_secc));

    context->running_data.b->relay_status_secc.pid = OPENCHAOJI_GBT27930_B_PGI_PUBLIC_RELAY_STATUS_SECC;

    context->running_data.b->relay_status_secc.contact_c1 = (hal_relay_status & 0x02) ? OPENCHAOJI_GBT27930_B_CONTACT_STATUS_CLOSED : OPENCHAOJI_GBT27930_B_CONTACT_STATUS_OPENED;
    context->running_data.b->relay_status_secc.contact_c2 = (hal_relay_status & 0x01) ? OPENCHAOJI_GBT27930_B_CONTACT_STATUS_CLOSED : OPENCHAOJI_GBT27930_B_CONTACT_STATUS_OPENED;

    OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_RELAY_STATUS_SECC, (uint8_t *)(&context->running_data.b->relay_status_secc), sizeof(context->running_data.b->relay_status_secc));

    OpenChaoJi_os_soft_timer_reset(&context->running_data.b->relay_status_secc_T1);

    return;
}

/**
 * @brief: 正常停机处理
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 * @param {uint8_t} end_code 停机码
 * @param {uint8_t} end_Reason 停机原因
 * @return {int} 停机阶段跳转MODULE_STATUS_ID
 */
static int OpenChaoJi_gbt27930_b_secc_stop_normal(struct OpenChaoJi_secc_context * context, uint8_t end_code, uint8_t end_Reason)       // 正常停机(中止报文不发)
{
    if(context->running_data.b->stop_info_secc_sent == 0)
    {
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, end_code, end_Reason);
    }
    LOG_WARNING("[%d]InfoStopCharge", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S0_NORMAL;
}

/**
 * @brief: 故障停机处理
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 * @param {uint8_t} end_code 停机码
 * @param {uint8_t} end_Reason 停机原因
 * @return {int} 停机阶段跳转MODULE_STATUS_ID
 */
static int OpenChaoJi_gbt27930_b_secc_stop_failed(struct OpenChaoJi_secc_context * context, uint8_t end_code, uint8_t end_Reason)       // 故障停机
{
    if(context->running_data.b->stop_info_secc_sent == 0)
    {
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, end_code, end_Reason);
    }

    LOG_ERR("[%d]ErrStopCharge", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S1_FAULT;
}

/**
 * @brief: 紧急停机处理
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 * @param {uint8_t} end_code 停机码
 * @param {uint8_t} end_Reason 停机原因
 * @return {int} 停机阶段跳转MODULE_STATUS_ID
 */
static int OpenChaoJi_gbt27930_b_secc_stop_emergency(struct OpenChaoJi_secc_context * context, uint8_t end_code, uint8_t end_Reason)       // 紧急停机
{
    if(context->running_data.b->stop_info_secc_sent == 0)
    {
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, end_code, end_Reason);
    }

    LOG_EMERG("[%d]EmergencyStopCharge", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S2_EMRGE;
}

/**
 * @brief: 根据功能协商结果查找下一个支持的FDC
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 * @param {OpenChaoJi_gbt27930_b_FCType} cur_fc_type 当前FC
 * @return {int} 返回协商的下一个FDC+FC
 */
static int OpenChaoJi_gbt27930_b_secc_find_next_support_fdc(struct OpenChaoJi_secc_context * context, enum OpenChaoJi_gbt27930_b_FCType cur_fc_type)
{
	switch (cur_fc_type)
	{
    case OPENCHAOJI_GBT27930_B_FC_TYPE_FUNC_NEGO:
        return ((OPENCHAOJI_GBT27930_B_FDC_PARAM_CONFIG_GENERAL << 8 ) | OPENCHAOJI_GBT27930_B_FC_TYPE_PARAM_CONFIG);

	case OPENCHAOJI_GBT27930_B_FC_TYPE_PARAM_CONFIG:
		if(context->running_data.b->func_nego.func_support_evcc.fdc_auth != 0)
		{
			return ((context->running_data.b->func_nego.func_support_evcc.fdc_auth << 8) | OPENCHAOJI_GBT27930_B_FC_TYPE_AUTH);
        }
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_AUTH == CONFIG_YES)
	case OPENCHAOJI_GBT27930_B_FC_TYPE_AUTH:
		if(context->running_data.b->func_nego.func_support_evcc.fdc_reserve != 0)
		{
			return ((context->running_data.b->func_nego.func_support_evcc.fdc_reserve << 8) | OPENCHAOJI_GBT27930_B_FC_TYPE_RESERVE);
		}
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_RESERVE == CONFIG_YES)
	case OPENCHAOJI_GBT27930_B_FC_TYPE_RESERVE:
		if(context->running_data.b->func_nego.func_support_evcc.fdc_selfcheck != 0)
		{
			return ((context->running_data.b->func_nego.func_support_evcc.fdc_selfcheck << 8) | OPENCHAOJI_GBT27930_B_FC_TYPE_SELFCHECK);
		}
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SELFCHECK == CONFIG_YES)
	case OPENCHAOJI_GBT27930_B_FC_TYPE_SELFCHECK:
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SUPPLY == CONFIG_YES)
		if(context->running_data.b->func_nego.func_support_evcc.fdc_supply != 0)
		{
			return ((context->running_data.b->func_nego.func_support_evcc.fdc_supply << 8) | OPENCHAOJI_GBT27930_B_FC_TYPE_SUPPLY);
		}
#endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SUPPLY == CONFIG_YES)
	case OPENCHAOJI_GBT27930_B_FC_TYPE_SUPPLY:
#endif
		if(context->running_data.b->func_nego.func_support_evcc.fdc_energy != 0)
		{
			return ((context->running_data.b->func_nego.func_support_evcc.fdc_energy << 8) | OPENCHAOJI_GBT27930_B_FC_TYPE_ENERGY);
		}

	case OPENCHAOJI_GBT27930_B_FC_TYPE_ENERGY:
        // !!! 服务统计模块不管是否配置, 必须经过STOPPING状态, 保证安全停机

		// if(context->running_data.b->func_nego.func_support_evcc.fdc_statistics != 0)
		// {
		// 	return ((context->running_data.b->func_nego.func_support_evcc.fdc_statistics<<8)|OPENCHAOJI_GBT27930_B_FC_TYPE_STATISTICS);
		// }
		return ((1 << 8) | OPENCHAOJI_GBT27930_B_FC_TYPE_SERVICE_STOPPING);

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_STATISTICS == CONFIG_YES)
	case OPENCHAOJI_GBT27930_B_FC_TYPE_STATISTICS:
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SERVICE_IDLE == CONFIG_YES)
		if(context->running_data.b->func_nego.func_support_evcc.fdc_service_idle != 0)
		{
			return ((context->running_data.b->func_nego.func_support_evcc.fdc_service_idle<<8)|OPENCHAOJI_GBT27930_B_FC_TYPE_SERVICE_IDLE);
		}
#endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SERVICE_IDLE == CONFIG_YES)
	case OPENCHAOJI_GBT27930_B_FC_TYPE_SERVICE_IDLE:
#endif
	default:
		return ((1 << 8) | OPENCHAOJI_GBT27930_B_FC_TYPE_SERVICE_STOPPING);
	}
}

/**
 * @brief: 查找下一个支持的功能模块
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 * @return {OpenChaoJi_secc_module *} 下一个功能模块状态表指针
 */
static const struct OpenChaoJi_secc_module * OpenChaoJi_gbt27930_b_secc_find_next_module(struct OpenChaoJi_secc_context * context)
{
	uint16_t fdc_fc_next;
	uint8_t	 fdc;
	uint8_t  fc;

    const struct OpenChaoJi_secc_module * curr_module = OpenChaoJi_secc_service_find_module(context->secc_gbt27930_system, context->current_module_status_id);
    enum OpenChaoJi_gbt27930_b_FCType cur_fc_type = curr_module->fc_type;

	fdc_fc_next = OpenChaoJi_gbt27930_b_secc_find_next_support_fdc(context, cur_fc_type);
	fdc = fdc_fc_next>>8;
	fc = fdc_fc_next&0xFF;

    return OpenChaoJi_secc_service_find_module_by_fdc(context->secc_gbt27930_system, fc, fdc);
}

/**
 * @brief: 查找下一个功能模块的S0状态
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 * @return {int} 返回下一个模块s0状态ID
 */
static int OpenChaoJi_gbt27930_b_secc_find_next_module_status(struct OpenChaoJi_secc_context * context)
{
    const struct OpenChaoJi_secc_module * next_module = OpenChaoJi_gbt27930_b_secc_find_next_module(context);

    return OPENCHAOJI_SECC_MODULE_STATUS_ID(next_module->module_id, 0);
}

/**
 * @brief: 发送下一阶段信息报文
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 */
static void OpenChaoJi_gbt27930_b_secc_next_phase_info_send(struct OpenChaoJi_secc_context * context)
{
    const struct OpenChaoJi_secc_module * next_module = OpenChaoJi_gbt27930_b_secc_find_next_module(context);

    OpenChaoJi_gbt27930_b_secc_phase_info_send(context, next_module->fc_type, next_module->fdc_type);

    return;
}

/* -------------- IDLE 模块 特来电 -------------- */
void OpenChaoJi_gbt27930_b_secc_prev_idle_s0_idle(struct OpenChaoJi_secc_context * context)
{
    OpenChaoJi_gbt27930_b_secc_reset_to_default(context);
}
void OpenChaoJi_gbt27930_b_secc_post_idle_s0_idle(struct OpenChaoJi_secc_context * context)
{
}

static int  OpenChaoJi_gbt27930_b_secc_loop_idle_s0_idle(struct OpenChaoJi_secc_context * context)
{
    if (context->app_permit_charge)
    {
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_TRIGGER_S0_CONNECT;
    }

    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_IDLE_S0_IDLE;
}

const struct OpenChaoJi_secc_module_status c_sytem_b_secc_status_array_idle[OPENCHAOJI_GBT27930_B_SECC_STATUS_IDLE_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_IDLE_S0_IDLE,
        .name = "Idle.S0",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_idle_s0_idle,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_idle_s0_idle,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_idle_s0_idle,
    },
};

const struct OpenChaoJi_secc_module c_gbt27930_b_secc_module_idle =
{
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_IDLE,
    .fc_type = 0,
    .fdc_type = 1,

    .name = "IDLE",
    .status_array = c_sytem_b_secc_status_array_idle,
    .status_array_len = OPENCHAOJI_GBT27930_B_SECC_STATUS_IDLE_NUM,
};




/* -------------- Trigger 模块 特来电 -------------- */
#define OpenChaoJi_gbt27930_b_secc_prev_trigger_s0_connect         NULL
#define OpenChaoJi_gbt27930_b_secc_post_trigger_s0_connect         NULL
// static void OpenChaoJi_gbt27930_b_secc_prev_trigger_s0_connect(struct OpenChaoJi_secc_context * context);
// static void OpenChaoJi_gbt27930_b_secc_post_trigger_s1_connect(struct OpenChaoJi_secc_context * context);
static int  OpenChaoJi_gbt27930_b_secc_loop_trigger_s0_connect(struct OpenChaoJi_secc_context * context)
{
    if(OpenChaoJi_secc_utility_pilot_is_evcc_connected(context->context_pilot))
    {
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_TRIGGER_S1_SESSION;
    }

    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_TRIGGER_S0_CONNECT;
}

static void OpenChaoJi_gbt27930_b_secc_prev_trigger_s1_session(struct OpenChaoJi_secc_context * context)
{
    LOG_STATUS_PREV("trigger s1 prev,close s1,start session");
    OpenChaoJi_secc_utility_pilot_b_permit_charge(context->context_pilot);    // 18487.C.4.3, 闭合S1,此时电压应为2.34V
    OpenChaoJi_secc_utility_session_start(context->context_session);        // 18487.C.4.3, 启动数据连接, 开始进行通信版本协商

    LOG_STATUS_PREV("trigger s1 prev,start Tc timer");
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->trigger.Tc, SYSTEM_PILOT_WAIT_SESSION_TIME_OUT); //超时时间大于版本协商时间+1s
}

static void OpenChaoJi_gbt27930_b_secc_post_trigger_s1_session(struct OpenChaoJi_secc_context * context)
{
    LOG_STATUS_POST("trigger s1 post,stop Tc timer");
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->trigger.Tc);
}

static int  OpenChaoJi_gbt27930_b_secc_loop_trigger_s1_session(struct OpenChaoJi_secc_context * context)
{
    enum OpenChaoJi_secc_utility_session_connect_status session_connect = OpenChaoJi_secc_utility_session_is_connected(context->context_session);
    if (session_connect == OPENCHAOJI_SECC_UTILITY_SESSION_CONNECT_STATUS_CONNECTED)
	{
		LOG_STATUS_CHANGE("Version negotiation succeed, start feature negotiation");
    	return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S0_INIT; // 18487.C.4.3 传输数据连接已建立且链路层版本协商成功
	}
    else
    {
        if (session_connect == OPENCHAOJI_SECC_UTILITY_SESSION_CONNECT_STATUS_DISCONNECTED)
        {
            LOG_STATUS_CHANGE("version negotiation is fault, close T1,T2, exit charging process");
            return OpenChaoJi_gbt27930_b_secc_stop_failed(context, 0, 0);
        }

        if(OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->trigger.Tc))
        {
            LOG_STATUS_CHANGE("Trigger.Tc Timeout");
            return OpenChaoJi_gbt27930_b_secc_stop_failed(context, 0, 0);
        }
    }

    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_TRIGGER_S1_SESSION;
}

const struct OpenChaoJi_secc_module_status c_sytem_b_secc_status_array_trigger[OPENCHAOJI_GBT27930_B_SECC_STATUS_TRIGGER_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_TRIGGER_S0_CONNECT,
        .name = "Trigger.S0.Connect",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_trigger_s0_connect,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_trigger_s0_connect,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_trigger_s0_connect,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_TRIGGER_S1_SESSION,
        .name = "Trigger.S1.Session",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_trigger_s1_session,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_trigger_s1_session,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_trigger_s1_session,
    },
};

const struct OpenChaoJi_secc_module c_gbt27930_b_secc_module_trigger =
{
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_TRIGGER,

    .fc_type = 1,
    .fdc_type = 1,

    .name = "TRIGGER",
    .status_array = c_sytem_b_secc_status_array_trigger,
    .status_array_len = OPENCHAOJI_GBT27930_B_SECC_STATUS_TRIGGER_NUM,
};




/* -------------- 功能协商 模块 嘉盛 -------------- */
static void  OpenChaoJi_gbt27930_b_secc_prev_func_nego_s0_init(struct OpenChaoJi_secc_context * context)
{
}
#define OpenChaoJi_gbt27930_b_secc_post_func_nego_s0_init         NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_func_nego_s0_init(struct OpenChaoJi_secc_context * context)
{
    // S0初始化
    LOG_STATUS_PREV("[%d]Nego S0 init start", context->tag);

    // 打开Tc
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->func_nego.Tc, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_FUNC_NEGO_SECC);
    LOG_STATUS_PREV("[%d]Nego Tc timer started", context->tag);

    // 发送"充电机支持功能"报文
    memcpy(context->running_data.b->func_nego.func_support_secc.fdc_support_auth,           context->running_data.b->app_start_parameter.fdc_support_auth, 8);
    memcpy(context->running_data.b->func_nego.func_support_secc.fdc_support_reserve,        context->running_data.b->app_start_parameter.fdc_support_reserve, 8);
    memcpy(context->running_data.b->func_nego.func_support_secc.fdc_support_selfcheck,      context->running_data.b->app_start_parameter.fdc_support_selfcheck, 8);
    memcpy(context->running_data.b->func_nego.func_support_secc.fdc_support_supply,         context->running_data.b->app_start_parameter.fdc_support_supply, 8);
    memcpy(context->running_data.b->func_nego.func_support_secc.fdc_support_energy,         context->running_data.b->app_start_parameter.fdc_support_energy, 8);
    memcpy(context->running_data.b->func_nego.func_support_secc.fdc_support_statistics,     context->running_data.b->app_start_parameter.fdc_support_statistics, 8);
    memcpy(context->running_data.b->func_nego.func_support_secc.fdc_support_service_idle,   context->running_data.b->app_start_parameter.fdc_support_service_idle, 8);

    OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_FUNC_NEGO_SECC, (uint8_t *)(&context->running_data.b->func_nego.func_support_secc), sizeof(context->running_data.b->func_nego.func_support_secc));
    LOG_STATUS_PREV("[%d]Nego S0 Send SECC Supported", context->tag);

    // 进入S1
    LOG_STATUS_CHANGE("[%d]Nego S0 To S1", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S1_NEGO;
}

#define OpenChaoJi_gbt27930_b_secc_prev_func_nego_s1_nego   NULL
#define OpenChaoJi_gbt27930_b_secc_post_func_nego_s1_nego   NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_func_nego_s1_nego(struct OpenChaoJi_secc_context * context)
{
    // 接收"车辆功能协商结果"报文
    if (context->running_data.b->func_nego.func_support_evcc_ok)
    {
        LOG_DATA_CHANGE("[%d]Nego S1 EVCC Supported Received", context->tag);

        // 全部必须项功能模块协商成功  (功能协商报文中目前有“预充及能量传输”与“系统自检”功能为必须项)
        if (context->running_data.b->func_nego.func_support_evcc.fdc_energy > 0 &&
            context->running_data.b->func_nego.func_support_evcc.fdc_selfcheck > 0)
        {
            LOG_STATUS_CHANGE("[%d]Nego S1 EVCC Necessary Model success", context->tag);
            // 发送"充电机阶段信息"报文
            OpenChaoJi_gbt27930_b_secc_next_phase_info_send(context);
            LOG_STATUS_CHANGE("[%d]Nego S1 Send SECC Phase info", context->tag);

            // 进入S2
            LOG_STATUS_CHANGE("[%d]Nego S1 To S2", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S2_PHASE_CONFIRM;
        }
        else
        {
            // 至少一个必须项功能模块不成功
            LOG_STATUS_CHANGE("[%d]Nego S1 EVCC Necessary Model error", context->tag);
            // 发送"中止_功能协商失败"报文
            OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_FUNC_NEGO);

            LOG_STATUS_CHANGE("[%d]Nego S1 Send SECC Nego Error Message", context->tag);

            // 进入S4
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S4_FAIL;
        }
    }

    // Tc定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->func_nego.Tc))
    {
        LOG_STATUS_CHANGE("[%d] Nego S1 Tc timer", context->tag);

        // 发送"中止_功能协商超时"报文
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TIMEOUT_FUNC_NEGO);

        // 进入S4
        LOG_STATUS_CHANGE("[%d]Nego S1 To S4", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S4_FAIL;
    }

    // 未收到, 未超时, 继续等待
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S1_NEGO;
}

#define OpenChaoJi_gbt27930_b_secc_prev_func_nego_s2_confirm   NULL
#define OpenChaoJi_gbt27930_b_secc_post_func_nego_s2_confirm   NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_func_nego_s2_confirm(struct OpenChaoJi_secc_context * context)
{
    // 接收"车辆阶段确认"报文
    if (context->running_data.b->phase_ack_evcc_ok)
    {
        LOG_DATA_CHANGE("[%d]Nego S2 EVCC Phase Confirm received", context->tag);

        // 确认成功
        if (context->running_data.b->phase_ack_evcc.phase_ack == OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED)
        {
            LOG_STATUS_CHANGE("[%d]Nego S2 EVCC Phase Confirm success", context->tag);
            // 进入S3
            LOG_STATUS_CHANGE("[%d]Nego S2 To S3", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S3_SUCCEED;
        }
        else
        {
          // 确认失败
          LOG_STATUS_CHANGE("[%d]Nego S2 EVCC Phase Confirm error", context->tag);
          // 发送"中止_阶段确认失败"报文
          OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_PHASE);

          // 进入S4
          LOG_STATUS_CHANGE("[%d]Nego S2 To S4", context->tag);
          return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S4_FAIL;
        }
    }

    // Tc定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->func_nego.Tc))
    {
        LOG_STATUS_CHANGE("[%d] Nego S2 Tc timer", context->tag);
        // 发送"中止_功能协商超时"报文
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TIMEOUT_FUNC_NEGO);

        LOG_STATUS_CHANGE("[%d]Nego S2 Send Nego Timeout Message success", context->tag);

        // 进入S4
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S4_FAIL;
    }

    // 未收到, 未超时, 继续等待
    LOG_STATUS_LOOP("[%d] Nego S2 Loop", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S2_PHASE_CONFIRM;
}

#define OpenChaoJi_gbt27930_b_secc_prev_func_nego_s3_succeed   NULL
#define OpenChaoJi_gbt27930_b_secc_post_func_nego_s3_succeed   NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_func_nego_s3_succeed(struct OpenChaoJi_secc_context * context)
{
    // 关闭Tc定时器
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->func_nego.Tc);
    LOG_STATUS_CHANGE("[%d] Nego S3 Tc closed", context->tag);

    // 进入参数配置功能模块FDC
    LOG_STATUS_CHANGE("[%d] Nego S3 To Param Config", context->tag);
    return OpenChaoJi_gbt27930_b_secc_find_next_module_status(context);
}

#define OpenChaoJi_gbt27930_b_secc_prev_func_nego_s4_failed   NULL
#define OpenChaoJi_gbt27930_b_secc_post_func_nego_s4_failed   NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_func_nego_s4_failed(struct OpenChaoJi_secc_context * context)
{
    // 关闭Tc定时器
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->func_nego.Tc);
    LOG_STATUS_CHANGE("[%d] Nego S4 Tc closed", context->tag);

    // 退出充电过程
    LOG_STATUS_CHANGE("[%d] Nego S4 To End", context->tag);

    return OpenChaoJi_gbt27930_b_secc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_FUNC_NEGO);
}

const struct OpenChaoJi_secc_module_status c_sytem_b_secc_status_array_func_nego[OPENCHAOJI_GBT27930_B_SECC_STATUS_FUNC_NEGO_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S0_INIT,
        .name = "Nego.S0.Init",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_func_nego_s0_init,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_func_nego_s0_init,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_func_nego_s0_init,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S1_NEGO,
        .name = "Nego.S1.Nego",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_func_nego_s1_nego,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_func_nego_s1_nego,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_func_nego_s1_nego,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S2_PHASE_CONFIRM,
        .name = "Nego.S2.Phase Confirm",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_func_nego_s2_confirm,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_func_nego_s2_confirm,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_func_nego_s2_confirm,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S3_SUCCEED,
        .name = "Nego.S3.Succeed",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_func_nego_s3_succeed,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_func_nego_s3_succeed,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_func_nego_s3_succeed,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S4_FAIL,
        .name = "Nego.S4.Fail",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_func_nego_s4_failed,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_func_nego_s4_failed,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_func_nego_s4_failed,
    },
};

const struct OpenChaoJi_secc_module c_gbt27930_b_secc_module_func_nego =
{
    .name = "Func_Nego",
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_FUNC_NEGO,
    .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_FUNC_NEGO,
    .fdc_type = OPENCHAOJI_GBT27930_B_FDC_FUNC_NEGO_GENERAL,

    .status_array = c_sytem_b_secc_status_array_func_nego,
    .status_array_len = OPENCHAOJI_GBT27930_B_SECC_STATUS_FUNC_NEGO_NUM,
};

/* -------------- 参数配置 模块 嘉盛 -------------- */
void OpenChaoJi_gbt27930_b_secc_prev_param_config_s0_init(struct OpenChaoJi_secc_context * context)
{
}
#define OpenChaoJi_gbt27930_b_secc_post_param_config_s0_init         NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_param_config_s0_init(struct OpenChaoJi_secc_context * context)
{
    // S0 初始化
    LOG_STATUS_PREV("[%d]Param Config S0 init start", context->tag);

    // 打开Tc
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->param_config.Tc, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_FUNC_PARAM_CONFIG_SECC);
    LOG_STATUS_PREV("[%d]Param Config S0 Tc timer start", context->tag);

    // 发送"充电机充电参数"报文
    context->running_data.b->param_config.param_config_secc.parameter_max_charging_volt     = context->running_data.b->app_start_parameter.parameter_max_charging_volt;
    context->running_data.b->param_config.param_config_secc.parameter_min_charging_volt     = context->running_data.b->app_start_parameter.parameter_min_charging_volt;
    context->running_data.b->param_config.param_config_secc.parameter_max_charging_curr     = context->running_data.b->app_start_parameter.parameter_max_charging_curr;
    context->running_data.b->param_config.param_config_secc.parameter_min_charging_curr     = context->running_data.b->app_start_parameter.parameter_min_charging_curr;
    context->running_data.b->param_config.param_config_secc.parameter_max_discharge_volt    = context->running_data.b->app_start_parameter.parameter_max_discharge_volt;
    context->running_data.b->param_config.param_config_secc.parameter_min_discharge_volt    = context->running_data.b->app_start_parameter.parameter_min_discharge_volt;
    context->running_data.b->param_config.param_config_secc.parameter_max_discharge_curr    = context->running_data.b->app_start_parameter.parameter_max_discharge_curr;
    context->running_data.b->param_config.param_config_secc.parameter_min_discharge_curr    = context->running_data.b->app_start_parameter.parameter_min_discharge_curr;
    context->running_data.b->param_config.param_config_secc.parameter_raise_rate_curr       = context->running_data.b->app_start_parameter.parameter_raise_rate_curr;
    context->running_data.b->param_config.param_config_secc.parameter_reduce_rate_curr      = context->running_data.b->app_start_parameter.parameter_reduce_rate_curr;

    OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_FUNC_PARAM_CONFIG_SECC, (uint8_t *)(&context->running_data.b->param_config.param_config_secc), sizeof(context->running_data.b->param_config.param_config_secc));
    LOG_STATUS_PREV("[%d]Param Config S0 Send SECC Param message", context->tag);

    // 进入S1
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_PARAM_CONFIG_S1_CONFIG;
}

#define OpenChaoJi_gbt27930_b_secc_prev_param_config_s1_config       NULL
#define OpenChaoJi_gbt27930_b_secc_post_param_config_s1_config       NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_param_config_s1_config(struct OpenChaoJi_secc_context * context)
{
    int param_OK = 0;   // 充电参数匹配判断标志位

    // 接收"车辆充电参数"报文
    if (context->running_data.b->param_config.param_config_evcc_ok)
    {
        LOG_DATA_CHANGE("[%d]Param Config S1 EVCC Param received", context->tag);

        // 充电参数匹配判断 (已经封装为函数，同目录见OpenChaoji_secc_gbt27930_b_param_match.c文件，供厂家修改参数匹配条件用)
        param_OK = OpenChaoJi_gbt27930_b_secc_param_match(context->running_data.b->func_nego.func_support_evcc.fdc_energy, context->running_data.b->param_config.param_config_evcc, context->running_data.b->param_config.param_config_secc);

        // 充电参数匹配
        if (param_OK)
        {
            LOG_STATUS_CHANGE("[%d]Param Config S1 EVCC Param matched", context->tag);
            // 发送"充电机阶段信息"报文
            OpenChaoJi_gbt27930_b_secc_next_phase_info_send(context);
            LOG_STATUS_CHANGE("[%d]Param Config S1 Send SECC Phase info message", context->tag);

            // 进入S2
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_PARAM_CONFIG_S2_PHASE_CONFIRM;
        }
        else
        {
            // 充电参数不匹配
            LOG_STATUS_CHANGE("[%d]Param Config S1 EVCC Param not matched", context->tag);
            // 发送"中止_参数不匹配"报文
            OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_PARAM_CONFIG);
            LOG_STATUS_CHANGE("[%d]Param Config S1 Send Param not matched message", context->tag);

            // 进入S4
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_PARAM_CONFIG_S4_FAIL;
        }
    }

    // 接收"中止_参数不匹配"报文
    if (context->running_data.b->stop_info_evcc_ok)
    {
        if (context->running_data.b->stop_info_evcc.end_Reason == OPENCHAOJI_GBT27930_B_END_REASON_EVCC_FAILED_PARAM_CONFIG)
        {
            LOG_STATUS_CHANGE("[%d]Param Config S1 EVCC TERM CONFIG", context->tag);
            // 进入S4
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_PARAM_CONFIG_S4_FAIL;
        }
    }

    // Tc定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->param_config.Tc))
    {
        LOG_STATUS_CHANGE("[%d]Param Config S1 Tc timeout", context->tag);
        // 发送"中止_参数配置超时"报文
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TIMEOUT_PARAM_CONFIG);
        LOG_STATUS_CHANGE("[%d]Param Config S1 Send Param Config Timeout message", context->tag);

        // 进入S4
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_PARAM_CONFIG_S4_FAIL;
    }

    // 未收到, 未超时, 继续等待
    LOG_STATUS_LOOP("[%d]Param Config S1 Loop", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_PARAM_CONFIG_S1_CONFIG;
}

#define OpenChaoJi_gbt27930_b_secc_prev_param_config_s2_confirm       NULL
#define OpenChaoJi_gbt27930_b_secc_post_param_config_s2_confirm       NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_param_config_s2_confirm(struct OpenChaoJi_secc_context * context)
{
    // 接收"车辆阶段确认"报文
    if (context->running_data.b->phase_ack_evcc_ok)
    {
        LOG_DATA_CHANGE("[%d]Param Config S2 EVCC Phase Confirm received", context->tag);
        // 确认成功
        if (context->running_data.b->phase_ack_evcc.phase_ack == OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED)
        {
            LOG_STATUS_CHANGE("[%d]Param Config S2 EVCC Phase Confirm success", context->tag);
            // 进入S3
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_PARAM_CONFIG_S3_SUCCEED;
        }
        else
        {
            LOG_STATUS_CHANGE("[%d]Param Config S2 EVCC Phase Confirm error", context->tag);
            // 进入S4
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_PARAM_CONFIG_S4_FAIL;
        }
    }

    // 未收到, 未超时, 继续等待
    LOG_STATUS_LOOP("[%d]Param Config S2 Loop", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_PARAM_CONFIG_S2_PHASE_CONFIRM;
}

#define OpenChaoJi_gbt27930_b_secc_prev_param_config_s3_succeed       NULL
#define OpenChaoJi_gbt27930_b_secc_post_param_config_s3_succeed       NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_param_config_s3_succeed(struct OpenChaoJi_secc_context * context)
{
    // 关闭Tc定时器
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->param_config.Tc);
    LOG_STATUS_CHANGE("[%d]Param Config S3 Tc close", context->tag);

    // 根据功能协商结果进入下一功能模块FDC
    return OpenChaoJi_gbt27930_b_secc_find_next_module_status(context);
}

#define OpenChaoJi_gbt27930_b_secc_prev_param_config_s4_failed          NULL
#define OpenChaoJi_gbt27930_b_secc_post_param_config_s4_failed          NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_param_config_s4_failed(struct OpenChaoJi_secc_context * context)
{
    // 关闭Tc定时器
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->param_config.Tc);
    LOG_STATUS_CHANGE("[%d]Param Config S4 Tc close", context->tag);

    // 退出充电过程
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_END_S0_FINISHING;
}

const struct OpenChaoJi_secc_module_status c_sytem_b_secc_status_array_param_config[OPENCHAOJI_GBT27930_B_SECC_STATUS_PARAM_CONFIG_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_PARAM_CONFIG_S0_INIT,
        .name = "Param Config.S0.Init",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_param_config_s0_init,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_param_config_s0_init,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_param_config_s0_init,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_PARAM_CONFIG_S1_CONFIG,
        .name = "Param Config.S1.Config",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_param_config_s1_config,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_param_config_s1_config,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_param_config_s1_config,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_PARAM_CONFIG_S2_PHASE_CONFIRM,
        .name = "Param Config.S2.Phase Confirm",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_param_config_s2_confirm,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_param_config_s2_confirm,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_param_config_s2_confirm,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_PARAM_CONFIG_S3_SUCCEED,
        .name = "Param Config.S3.Succeed",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_param_config_s3_succeed,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_param_config_s3_succeed,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_param_config_s3_succeed,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_PARAM_CONFIG_S4_FAIL,
        .name = "Param Config.S4.Fail",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_param_config_s4_failed,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_param_config_s4_failed,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_param_config_s4_failed,
    },
};

const struct OpenChaoJi_secc_module c_gbt27930_b_secc_module_param_config =
{
    .name = "Param Config",
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_PARAM_CONFIG,
    .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_PARAM_CONFIG,
    .fdc_type = OPENCHAOJI_GBT27930_B_FDC_PARAM_CONFIG_GENERAL,
    .status_array = c_sytem_b_secc_status_array_param_config,
    .status_array_len = OPENCHAOJI_GBT27930_B_SECC_STATUS_PARAM_CONFIG_NUM,
};




/* -------------- 授权(RFID) 模块 鲁软 -------------- */
#define OpenChaoJi_gbt27930_b_secc_prev_auth_rfid_s0_init         NULL
#define OpenChaoJi_gbt27930_b_secc_post_auth_rfid_s0_init         NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_auth_rfid_s0_init(struct OpenChaoJi_secc_context * context)
{
    // 初始化
    LOG_STATUS_PREV("[%d]Auth RFID S0 init start", context->tag);

    // 创建并打开Tc
    if(context->running_data.b->auth_rfid.rfid_param_secc.m_time != 0)
    {
        context->running_data.b->auth_rfid.Tc.timeout_ms = ((uint32_t)context->running_data.b->auth_rfid.rfid_param_secc.m_time) * 60000;
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->auth_rfid.Tc, context->running_data.b->auth_rfid.Tc.timeout_ms);
    }
    else
    {
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->auth_rfid.Tc, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_AUTH_RFID_TC_SECC);
    }

    LOG_STATUS_PREV("[%d]Auth RFID S0 Tc timer started", context->tag);

    // 发送"充电机鉴权参数_开始"报文
    context->running_data.b->auth_rfid.rfid_param_secc.m_time = context->running_data.b->app_start_parameter.rfid_auth_m_time; // APP_START_PARAM 此处由app填充
    context->running_data.b->auth_rfid.rfid_param_secc.c_authen_status = OPENCHAOJI_GBT27930_B_SECC_AUTH_STATUS_START_CONTINUE;//开始
    OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_AUTH_RFID_PARAM_SECC,(uint8_t *)(&context->running_data.b->auth_rfid.rfid_param_secc),sizeof(context->running_data.b->auth_rfid.rfid_param_secc));

    //创建打开t1
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->auth_rfid.T1, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_AUTH_RFID_PARAM_SECC);
    LOG_STATUS_PREV("[%d]Auth RFID S0 T1 timer started", context->tag);

    // 进入S1
    LOG_STATUS_CHANGE("[%d]Auth RFID S0 To S1", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S1_SCAN_CARD;
}


#define OpenChaoJi_gbt27930_b_secc_prev_auth_rfid_s1_wait   NULL
#define OpenChaoJi_gbt27930_b_secc_post_auth_rfid_s1_wait   NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_auth_rfid_s1_wait(struct OpenChaoJi_secc_context * context)
{
    // 接收"车辆鉴权等待"报文
    if (context->running_data.b->auth_rfid.rfid_wait_evcc_ok == 1)
    {
        LOG_STATUS_LOOP("[%d]Auth RFID S1 Recv Vehicle Waiting", context->tag);
        if(context->running_data.b->auth_rfid.rfid_wait_evcc.v_authen_status == OPENCHAOJI_GBT27930_B_EVCC_AUTH_STATUS_WAIT_REJECTED)//不同意等待
        {
            // 进入S5
            LOG_STATUS_CHANGE("[%d]Auth RFID S1 To S5", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S5_FAIL;
        }
        else // (context->running_data.b->auth_rfid.rfid_wait_evcc.v_authen_status == OPENCHAOJI_GBT27930_B_EVCC_AUTH_STATUS_WAIT_CONTINUE)//同意等待
        {
            // 保持S1
            LOG_STATUS_LOOP("[%d]Auth RFID S1 Loop", context->tag);
        }
    }

    // 向App获取（rfid成功状态）
    context->running_data.b->auth_rfid.app_auth_status_rfid = OpenChaoJi_secc_app_check_auth_rfid(context);
    if (context->running_data.b->auth_rfid.app_auth_status_rfid != SECC_APP_AUTH_STATUS_CHECKING)//鉴权完成(无论成功或失败)状态 进入S2
    {
        // 发送充电机鉴权参数_完成报文
        context->running_data.b->auth_rfid.rfid_param_secc.c_authen_status = OPENCHAOJI_GBT27930_B_SECC_AUTH_STATUS_FINISHED;
        LOG_STATUS_CHANGE("[%d]Auth RFID S2 Send Charger RFID Param success", context->tag);
        OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_AUTH_RFID_PARAM_SECC,(uint8_t *)(&context->running_data.b->auth_rfid.rfid_param_secc),sizeof(context->running_data.b->auth_rfid.rfid_param_secc));

        // 进入S2
        LOG_STATUS_CHANGE("[%d] Auth RFID S1 To S2");
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S2_AUTH_COMPLETE;
    }

    // T1定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->auth_rfid.T1))
    {
        LOG_MSG_TIMEOUT("[%d]Auth RFID S1 T1 timeout and reset", context->tag);

        //发送充电机鉴权参数_开始/持续报文，保持S1
        OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_AUTH_RFID_PARAM_SECC,(uint8_t *)(&context->running_data.b->auth_rfid.rfid_param_secc),sizeof(context->running_data.b->auth_rfid.rfid_param_secc));

        //重置t1
        OpenChaoJi_os_soft_timer_reset(&context->running_data.b->auth_rfid.T1);
    }

    // Tc定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->auth_rfid.Tc))
    {
        LOG_STATUS_CHANGE("[%d]Auth RFID S1 Tc timeout", context->tag);

        //发送"中止_鉴权超时"报文
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TIMEOUT_AUTH);

        // 进入S5
        LOG_STATUS_CHANGE("[%d]Auth RFID S1 To S5", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S5_FAIL;
    }

    // 未收到, 未超时, 继续等待
    LOG_STATUS_LOOP("[%d] Auth RFID S1 Loop", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S1_SCAN_CARD;
}


#define OpenChaoJi_gbt27930_b_secc_prev_auth_rfid_s2_complete   NULL
#define OpenChaoJi_gbt27930_b_secc_post_auth_rfid_s2_complete   NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_auth_rfid_s2_complete(struct OpenChaoJi_secc_context * context)
{
    //关闭T1
    LOG_STATUS_CHANGE("[%d]Auth RFID S2 T1 timer stop", context->tag);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.T1);

    if (context->running_data.b->auth_rfid.app_auth_status_rfid == SECC_APP_AUTH_STATUS_OK)    //鉴权成功
    {
        //发送充电机鉴权结果_成功报文，进入S3
        LOG_STATUS_CHANGE("[%d]Auth RFID S2 Send Charger RFID Result success", context->tag);
        context->running_data.b->auth_rfid.rfid_result_secc.authen_result = OPENCHAOJI_GBT27930_B_AUTH_RESULT_SUCCEED;
        OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_AUTH_RFID_RESULT_SECC,(uint8_t *)(&context->running_data.b->auth_rfid.rfid_result_secc),sizeof(context->running_data.b->auth_rfid.rfid_result_secc));

		// 发送"充电机阶段信息"报文
        OpenChaoJi_gbt27930_b_secc_next_phase_info_send(context);

		LOG_STATUS_CHANGE("[%d]Auth RFID S2 succeed", context->tag);
        //进入S3
        LOG_STATUS_CHANGE("[%d]Auth RFID S1 To S3", context->tag);

        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S3_PHASE_CONFIRM;
    }
    else    // if(context->running_data.b->app_auth_status == SECC_APP_AUTH_STATUS_FAIL)
    {
        //发送充电机鉴权结果_失败报文，进入S5
        LOG_STATUS_CHANGE("[%d]Auth RFID S2 Send Charge Auth failed", context->tag);
        context->running_data.b->auth_rfid.rfid_result_secc.authen_result = OPENCHAOJI_GBT27930_B_AUTH_RESULT_FAILED;
        OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_AUTH_RFID_RESULT_SECC,(uint8_t *)(&context->running_data.b->auth_rfid.rfid_result_secc),sizeof(context->running_data.b->auth_rfid.rfid_result_secc));
        //进入S3
        LOG_STATUS_CHANGE("[%d]Auth RFID S1 To S5", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S5_FAIL;
    }

    // Tc定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->auth_rfid.Tc))
    {
        LOG_STATUS_CHANGE("[%d] Auth RFID S2 Tc timeout", context->tag);

        //发送"中止_鉴权超时"报文
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TIMEOUT_AUTH);

        // 进入S5
        LOG_STATUS_CHANGE("[%d]Auth RFID S2 To S5", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S5_FAIL;
    }

    LOG_STATUS_LOOP("[%d] Auth RFID S2 Loop", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S2_AUTH_COMPLETE;
}

#define OpenChaoJi_gbt27930_b_secc_prev_auth_rfid_s3_confirm   NULL
#define OpenChaoJi_gbt27930_b_secc_post_auth_rfid_s3_confirm   NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_auth_rfid_s3_confirm(struct OpenChaoJi_secc_context * context)
{
    // 接收"车辆阶段确认"报文
    if (context->running_data.b->phase_ack_evcc_ok)
    {
        LOG_STATUS_CHANGE("[%d]Auth RFID S3 Recv Vehicle Phase Confirm", context->tag);
        // 确认成功
        if (context->running_data.b->phase_ack_evcc.phase_ack == OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED)
        {
            LOG_STATUS_CHANGE("[%d]Vehicle Phase Confirm succeed", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S4_SUCCEED;
        }
        else if(context->running_data.b->phase_ack_evcc.phase_ack == OPENCHAOJI_GBT27930_B_PHASE_ACK_FAILED)
        {
            // 发送"中止_阶段确认失败"报文
            LOG_STATUS_CHANGE("[%d]Auth RFID S3 Send Stop Phase Confirm Failed", context->tag);
            OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_PHASE);

            // 进入S5
            LOG_STATUS_CHANGE("[%d]Auth RFID S3 To S5", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S5_FAIL;
        }
    }

    // Tc定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->auth_rfid.Tc))
    {
        LOG_STATUS_CHANGE("[%d] Auth RFID S3 Tc timeout", context->tag);

        //发送"中止_鉴权超时"报文
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TIMEOUT_AUTH);

        // 进入S5
        LOG_STATUS_CHANGE("[%d]Auth RFID S3 To S5", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S5_FAIL;
    }

    LOG_STATUS_LOOP("[%d] Auth RFID S3 loop", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S3_PHASE_CONFIRM;
}

#define OpenChaoJi_gbt27930_b_secc_prev_auth_rfid_s4_succeed   NULL
#define OpenChaoJi_gbt27930_b_secc_post_auth_rfid_s4_succeed   NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_auth_rfid_s4_succeed(struct OpenChaoJi_secc_context * context)
{
    // 关闭Tc T1
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.Tc);
    LOG_STATUS_CHANGE("[%d]Auth RFID S4 Tc Stoped", context->tag);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.T1);
    LOG_STATUS_CHANGE("[%d]Auth RFID S4 T1 Stoped", context->tag);

    // 进入下一功能模块 系统自检
    return  OpenChaoJi_gbt27930_b_secc_find_next_module_status(context);
}

#define OpenChaoJi_gbt27930_b_secc_prev_auth_rfid_s5_fail   NULL
#define OpenChaoJi_gbt27930_b_secc_post_auth_rfid_s5_fail   NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_auth_rfid_s5_fail(struct OpenChaoJi_secc_context * context)
{
    // 关闭Tc T1
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.Tc);
    LOG_STATUS_CHANGE("[%d]Auth RFID S5 Tc Stoped", context->tag);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.T1);
    LOG_STATUS_CHANGE("[%d]Auth RFID S5 T1 Stoped", context->tag);

    //退出充电过程;
    LOG_STATUS_CHANGE("[%d]Auth RFID S5 To Stop Fail", context->tag);
    return  OpenChaoJi_gbt27930_b_secc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_AUTH);
}

//Q:1.向上获取鉴权三态  2.FDC跳转 3.去除fail
const struct OpenChaoJi_secc_module_status c_sytem_b_secc_status_array_auth_rfid[OPENCHAOJI_GBT27930_B_SECC_STATUS_AUTH_RFID_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S0_INIT,
        .name = "RFID.S0.Init",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_auth_rfid_s0_init,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_auth_rfid_s0_init,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_auth_rfid_s0_init,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S1_SCAN_CARD,
        .name = "RFID.S1.Wait",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_auth_rfid_s1_wait,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_auth_rfid_s1_wait,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_auth_rfid_s1_wait,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S2_AUTH_COMPLETE,
        .name = "RFID.S2.Complete",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_auth_rfid_s2_complete,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_auth_rfid_s2_complete,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_auth_rfid_s2_complete,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S3_PHASE_CONFIRM,
        .name = "RFID.S3.Confirm",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_auth_rfid_s3_confirm,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_auth_rfid_s3_confirm,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_auth_rfid_s3_confirm,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S4_SUCCEED,
        .name = "RFID.S4.Succeed",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_auth_rfid_s4_succeed,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_auth_rfid_s4_succeed,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_auth_rfid_s4_succeed,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_RFID_S5_FAIL,
        .name = "RFID.S5.Fail",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_auth_rfid_s5_fail,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_auth_rfid_s5_fail,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_auth_rfid_s5_fail,
    },
};

const struct OpenChaoJi_secc_module c_gbt27930_b_secc_module_auth_rfid =
{
    .name = "Auth RFID",
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_AUTH_RFID,
    .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_AUTH,
    .fdc_type = OPENCHAOJI_GBT27930_B_FDC_AUTH_RFID,

    .status_array = c_sytem_b_secc_status_array_auth_rfid,
    .status_array_len = OPENCHAOJI_GBT27930_B_SECC_STATUS_AUTH_RFID_NUM,
};




/* -------------- 授权(EVIN) 模块 鲁软 -------------- */
//Q:FDC tc 5s过短
#define OpenChaoJi_gbt27930_b_secc_prev_auth_evin_s0_init         NULL
#define OpenChaoJi_gbt27930_b_secc_post_auth_evin_s0_init         NULL
// 初始化
static int  OpenChaoJi_gbt27930_b_secc_loop_auth_evin_s0_init(struct OpenChaoJi_secc_context * context)
{
    // 初始化
    LOG_STATUS_PREV("[%d]Auth EVIN S0 Init", context->tag);

    // 打开Tc
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->auth_evin.Tc, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_AUTH_EVIN_TC_SECC);
    LOG_STATUS_PREV("[%d]Auth EVIN S0 Tc Start", context->tag);

    // 发送"鉴权请求"报文
    LOG_STATUS_PREV("[%d]Auth EVIN S0 Send Auth Request", context->tag);
    OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_AUTH_EVIN_REQ_SECC,(uint8_t *)(&context->running_data.b->auth_evin.evin_req_secc),sizeof(context->running_data.b->auth_evin.evin_req_secc));

    // 进入S1
    LOG_STATUS_CHANGE("[%d]Auth EVIN S0 To S1", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S1_AUTH_PROCESS;
}

// 鉴权过程
#define OpenChaoJi_gbt27930_b_secc_prev_auth_evin_s1_process         NULL
#define OpenChaoJi_gbt27930_b_secc_post_auth_evin_s1_process         NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_auth_evin_s1_process(struct OpenChaoJi_secc_context * context)
{
    // 接收"车辆鉴权参数"报文
    if (context->running_data.b->auth_evin.evin_param_evcc_ok)
    {
        LOG_DATA_NORMAL("[%d]Auth EVIN S1 Recv Vehicle Auth Param", context->tag);

        // 向App获取（evin成功状态）
        context->running_data.b->auth_evin.app_auth_status_evin = OpenChaoJi_secc_app_check_auth_evin(context, context->running_data.b->auth_evin.evin_param_evcc.evin);
    }

    if (context->running_data.b->auth_evin.app_auth_status_evin != SECC_APP_AUTH_STATUS_CHECKING)//鉴权完成(无论成功或失败)状态 进入S2
    {
        LOG_STATUS_CHANGE("[%d]Auth EVIN S1 Auth Complete To S2", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S2_AUTH_COMPLETE;
    }

    // Tc定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->auth_evin.Tc))
    {
        LOG_STATUS_CHANGE("[%d]Auth EVIN S1 Tc Timeout", context->tag);

        //发送"中止_鉴权超时"报文
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TIMEOUT_AUTH);

        // 进入S5
        LOG_STATUS_CHANGE("[%d]Auth EVIN S1 To S5", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S5_FAIL;
    }

    LOG_STATUS_LOOP("[%d] Auth EVIN S1 loop", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S1_AUTH_PROCESS;
}

// 完成鉴权
#define OpenChaoJi_gbt27930_b_secc_prev_auth_evin_s2_complete         NULL
#define OpenChaoJi_gbt27930_b_secc_post_auth_evin_s2_complete         NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_auth_evin_s2_complete(struct OpenChaoJi_secc_context * context)
{
    if(context->running_data.b->auth_evin.app_auth_status_evin == SECC_APP_AUTH_STATUS_OK)// 鉴权成功
    {
        LOG_STATUS_CHANGE("[%d]Auth EVIN S2 Complete", context->tag);

        // 发送鉴权结果_成功
        context->running_data.b->auth_evin.evin_result_secc.authen_result = OPENCHAOJI_GBT27930_B_AUTH_RESULT_SUCCEED;
        OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_AUTH_EVIN_RESULT_SECC,(uint8_t *)(&context->running_data.b->auth_evin.evin_result_secc),sizeof(context->running_data.b->auth_evin.evin_result_secc));

        // 发送充电机阶段确认
        OpenChaoJi_gbt27930_b_secc_next_phase_info_send(context);

        // 进入S3
        LOG_STATUS_CHANGE("[%d]Auth EVIN S2 To S3", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S3_PHASE_CONFIRM;
    }
    else // if(context->running_data.b->app_auth_status == SECC_APP_AUTH_STATUS_FAIL)
    {
        // 发送鉴权结果_失败
        LOG_STATUS_CHANGE("[%d]Auth EVIN S3 Send Auth Result Fail", context->tag);
        context->running_data.b->auth_evin.evin_result_secc.authen_result = OPENCHAOJI_GBT27930_B_AUTH_RESULT_FAILED;
        OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_AUTH_EVIN_RESULT_SECC,(uint8_t *)(&context->running_data.b->auth_evin.evin_result_secc),sizeof(context->running_data.b->auth_evin.evin_result_secc));

        // 进入S5
        LOG_STATUS_CHANGE("[%d]Auth EVIN S2 To S5", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S5_FAIL;
    }

    // Tc定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->auth_evin.Tc))
    {
        LOG_STATUS_CHANGE("[%d]Auth EVIN S2 Tc Timeout", context->tag);

        //发送"中止_鉴权超时"报文
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TIMEOUT_AUTH);

        // 进入S5
        LOG_STATUS_CHANGE("[%d]Auth EVIN S2 To S5", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S5_FAIL;
    }

    LOG_STATUS_LOOP("[%d] Auth EVIN S2 loop", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S2_AUTH_COMPLETE;
}

// 阶段确认
#define OpenChaoJi_gbt27930_b_secc_prev_auth_evin_s3_confirm         NULL
#define OpenChaoJi_gbt27930_b_secc_post_auth_evin_s3_confirm         NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_auth_evin_s3_confirm(struct OpenChaoJi_secc_context * context)
{
    // 接收"车辆阶段确认"报文
    if (context->running_data.b->phase_ack_evcc_ok)
    {
        LOG_STATUS_CHANGE("[%d]Auth EVIN S3 Recv Vehicle Phase Confirm", context->tag);
        // 确认成功
        if (context->running_data.b->phase_ack_evcc.phase_ack == OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED)
        {
            LOG_STATUS_CHANGE("[%d]Auth EVIN S3 Phase Confirm Succeed To S4", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S4_SUCCEED;
        }
        else
        {
            // 发送"中止_阶段确认失败"报文
            OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_PHASE);

            LOG_STATUS_CHANGE("[%d]Auth EVIN S3 Phase Confirm Failed To S5", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S5_FAIL;
        }

        // Tc定时器到
        if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->auth_evin.Tc))
        {
            LOG_STATUS_CHANGE("[%d]Auth EVIN S3 Phase Confirm Tc Timeout", context->tag);

            //发送"中止_鉴权超时"报文
            OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TIMEOUT_AUTH);

            // 进入S5
            LOG_STATUS_CHANGE("[%d]Auth EVIN S3 Phase Confirm Timeout To S5", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S5_FAIL;
        }
    }

    LOG_STATUS_LOOP("[%d]Auth EVIN S3 Loop", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S3_PHASE_CONFIRM;
}

// 成功
#define OpenChaoJi_gbt27930_b_secc_prev_auth_evin_s4_succeed         NULL
#define OpenChaoJi_gbt27930_b_secc_post_auth_evin_s4_succeed         NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_auth_evin_s4_succeed(struct OpenChaoJi_secc_context * context)
{
    // 关闭Tc
    LOG_STATUS_CHANGE("[%d]Auth EVIN S4 Close Tc ,To Next Status", context->tag);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_evin.Tc);

    //进入下一个功能模块;
    return OpenChaoJi_gbt27930_b_secc_find_next_module_status(context);
}

// 完成鉴权
#define OpenChaoJi_gbt27930_b_secc_prev_auth_evin_s5_fail         NULL
#define OpenChaoJi_gbt27930_b_secc_post_auth_evin_s5_fail         NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_auth_evin_s5_fail(struct OpenChaoJi_secc_context * context)
{
    // 关闭Tc
    LOG_STATUS_CHANGE("[%d]Auth EVIN S5 Close Tc ,To Stop Fail", context->tag);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_evin.Tc);

    return OpenChaoJi_gbt27930_b_secc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_AUTH);
}

const struct OpenChaoJi_secc_module_status c_sytem_b_secc_status_array_auth_evin[OPENCHAOJI_GBT27930_B_SECC_STATUS_AUTH_EVIN_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S0_INIT,
        .name = "EVIN.S0.Init",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_auth_evin_s0_init,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_auth_evin_s0_init,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_auth_evin_s0_init,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S1_AUTH_PROCESS,
        .name = "EVIN.S1.AuthProcess",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_auth_evin_s1_process,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_auth_evin_s1_process,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_auth_evin_s1_process,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S2_AUTH_COMPLETE,
        .name = "EVIN.S2.AuthComplete",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_auth_evin_s2_complete,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_auth_evin_s2_complete,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_auth_evin_s2_complete,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S3_PHASE_CONFIRM,
        .name = "EVIN.S3.PhaseConfirm",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_auth_evin_s3_confirm,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_auth_evin_s3_confirm,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_auth_evin_s3_confirm,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S4_SUCCEED,
        .name = "EVIN.S4.Succeed",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_auth_evin_s4_succeed,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_auth_evin_s4_succeed,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_auth_evin_s4_succeed,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_AUTH_EVIN_S5_FAIL,
        .name = "EVIN.S5.Fail",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_auth_evin_s5_fail,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_auth_evin_s5_fail,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_auth_evin_s5_fail,
    },
};

const struct OpenChaoJi_secc_module c_gbt27930_b_secc_module_auth_evin =
{
    .name = "Auth EVIN",

    .module_id = OPENCHAOJI_GBT27930_B_MODULE_AUTH_EVIN,
    .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_AUTH,
    .fdc_type = OPENCHAOJI_GBT27930_B_FDC_AUTH_EVIN,

    .status_array = c_sytem_b_secc_status_array_auth_evin,
    .status_array_len = OPENCHAOJI_GBT27930_B_SECC_STATUS_AUTH_EVIN_NUM,
};



/* -------------- 预约 模块 (暂空) -------------- */






/* -------------- 系统自检 模块 领充 -------------- */

// 27930 表G.5 S0 初始化
static void OpenChaoJi_gbt27930_b_secc_prev_selfcheck_s0_init(struct OpenChaoJi_secc_context * context)
{
	LOG_STATUS_PREV("[%d]Self Check S0 Init Prev -> S0 Init Loop", context->tag);
}
#define OpenChaoJi_gbt27930_b_secc_post_selfcheck_s0_init         NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_selfcheck_s0_init(struct OpenChaoJi_secc_context * context)
{
   	//打开Tc
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->self_check.Tc, OPENCHAOJI_GBT27930_B_TIMEOUT_SELFCHECK_PHASE_SECC);
    LOG_STATUS_CHANGE("[%d]Self Check S0 Tc Start", context->tag);

	//发送“充电机自检   状态_未检测” 报文
    context->running_data.b->self_check.selfcheck_status_secc.check_adhesion_status = OPENCHAOJI_GBT27930_B_CHECK_TYPE_NOT_CHECK;
	context->running_data.b->self_check.selfcheck_status_secc.check_insulation_status = OPENCHAOJI_GBT27930_B_CHECK_TYPE_NOT_CHECK;
	context->running_data.b->self_check.selfcheck_status_secc.check_short_circuit_status = OPENCHAOJI_GBT27930_B_CHECK_TYPE_NOT_CHECK;

    OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_FUNC_SELFCHECK_STATUS_SECC,(uint8_t *)(&context->running_data.b->self_check.selfcheck_status_secc),sizeof(context->running_data.b->self_check.selfcheck_status_secc));
    LOG_STATUS_CHANGE("[%d]Self Check S0 Send Charge Self Check Status No Detection", context->tag);

    // 开启  T1
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->self_check.T1, OPENCHAOJI_GBT27930_B_PID_TIMELOOP_FUNC_SELFCHECK_STATUS_SECC);
    LOG_STATUS_CHANGE("[%d]Self Check S0 T1 Start", context->tag);

	//进入S1
    LOG_STATUS_CHANGE("[%d]Self Check S0 Init -> S1 Elocked", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S1_ELOCKED;
}

// 27930 表G.5 S1 等待电子锁锁止
#define OpenChaoJi_gbt27930_b_secc_prev_selfcheck_s1_elocked      NULL
#define OpenChaoJi_gbt27930_b_secc_post_selfcheck_s1_elocked      NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_selfcheck_s1_elocked(struct OpenChaoJi_secc_context * context)
{
	//接收“车辆电子锁状态”报文
	if (context->running_data.b->latchging_status_evcc_ok)
	{
		//电子锁锁止
		if (context->running_data.b->latchging_status_evcc.latching_status == OPENCHAOJI_GBT27930_B_LATCHING_STATUS_TYPE_LOCKED)
		{
			LOG_STATUS_CHANGE("[%d]Self Check S1 Elocked -> S2 Checking", context->tag);

			return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S2_CHECKING;
		}
	}

	//T1定时器到
	if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->self_check.T1))
	{
		LOG_STATUS_CHANGE("[%d]Self Check S1 T1 Timeout, Reset T1", context->tag);

		// 发送“充电机自检状态_未检测”报文,保持Sl
        OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_FUNC_SELFCHECK_STATUS_SECC, (uint8_t *)(&context->running_data.b->self_check.selfcheck_status_secc), sizeof(context->running_data.b->self_check.selfcheck_status_secc));
        LOG_STATUS_CHANGE("[%d]Self Check S1 Send Charge Self Check Status: No Detection", context->tag);

		//重置T1
		OpenChaoJi_os_soft_timer_reset(&context->running_data.b->self_check.T1);
    }

	//Tc定时器到
	if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->self_check.Tc))
	{
        LOG_STATUS_CHANGE("[%d]Self Check S1 Tc Timeout", context->tag);

		// 发送“中止  电子锁锁止异常”报文,进入S5
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_SELFCHECK);
        LOG_STATUS_CHANGE("[%d]Self Check S1 Send Stop Electronic Locking Abnormality", context->tag);

        LOG_STATUS_CHANGE("[%d]Self Check S1 Elocked -> S5 Fail", context->tag);
		return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S5_FAIL;
    }

	//保持S1
    LOG_STATUS_LOOP("[%d]Self Check Keep S1 Elocked", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S1_ELOCKED;
}

// 27930 表G.5 S2 系统自检
static void OpenChaoJi_gbt27930_b_secc_prev_selfcheck_s2_checking(struct OpenChaoJi_secc_context * context)
{
    LOG_NOTICE("[%d]Self Check Keep S1 Elocked", context->tag);

    //自检电压目标值
    uint32_t selfcheck_voltage;
    selfcheck_voltage = context->running_data.b->param_config.param_config_secc.parameter_max_charging_volt;
    if(selfcheck_voltage > context->running_data.b->param_config.param_config_evcc.parameter_max_charging_volt)
    {
        selfcheck_voltage = context->running_data.b->param_config.param_config_evcc.parameter_max_charging_volt;
    }

    LOG_STATUS_PREV("[%d]Self Check Voltage: %d", context->tag, selfcheck_voltage);
    LOG_STATUS_PREV("[%d]Self Check S2 Checking Prev -> S2 Checking Loop", context->tag);
    OpenChaoJi_secc_hal_selfcheck_request_start(context->hal_handle,selfcheck_voltage);
}

static void OpenChaoJi_gbt27930_b_secc_post_selfcheck_s2_checking(struct OpenChaoJi_secc_context * context)
{
    LOG_STATUS_POST("[%d]Self Check S2 Checking Post, Request Stop", context->tag);
	//请求停止
	OpenChaoJi_secc_hal_selfcheck_request_stop(context->hal_handle);
}

static int  OpenChaoJi_gbt27930_b_secc_loop_selfcheck_s2_checking(struct OpenChaoJi_secc_context * context)
{
    LOG_STATUS_LOOP("[%d]Self Check S2 Checking", context->tag);

	struct OpenChaoJi_secc_hal_selfdata self_check_inf;

	//接收“车辆电子锁状态”报文
	if (context->running_data.b->latchging_status_evcc_ok)
	{
		//电子锁未锁止 发送“中止_电子锁锁止异常”报文，进入S5
		if (context->running_data.b->latchging_status_evcc.latching_status != OPENCHAOJI_GBT27930_B_LATCHING_STATUS_TYPE_LOCKED)
		{
            OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_SELFCHECK);
            LOG_STATUS_CHANGE("[%d]Self Check S2 Checking Send Stop Electronic Locking Abnormality", context->tag);

			LOG_STATUS_CHANGE("[%d]Self Check S2 Checking -> S5 Fail", context->tag);
			return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S5_FAIL;
        }
	}

	self_check_inf = OpenChaoJi_secc_hal_selfcheck_get_result(context->hal_handle);

	LOG_STATUS_LOOP("self_check_inf=%d.%d.%d.%d.%d.%d", self_check_inf.selfsta_adhesion, self_check_inf.selfsta_short, self_check_inf.selfsta_imd
		, self_check_inf.selfres_adhesion, self_check_inf.selfres_short, self_check_inf.selfres_imd);

	//T1定时器到
	if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->self_check.T1))
	{
        LOG_MSG_TIMEOUT("[%d]Self Check S2 Checking T1 Timeout, re-send status", context->tag);
		//发送“充电机自检状态_未检测/检测中”报文，保持S2

	    context->running_data.b->self_check.selfcheck_status_secc.check_adhesion_status
												= self_check_inf.selfsta_adhesion - SELFSTA_ADHESION_NOTSTART;

		context->running_data.b->self_check.selfcheck_status_secc.check_insulation_status
												= self_check_inf.selfsta_imd - SELFSTA_IMD_NOTSTART;

		context->running_data.b->self_check.selfcheck_status_secc.check_short_circuit_status
												= self_check_inf.selfsta_short - SELFSTA_SHORT_NOTSTART;

        OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_FUNC_SELFCHECK_STATUS_SECC, (uint8_t *)(&context->running_data.b->self_check.selfcheck_status_secc), sizeof(context->running_data.b->self_check.selfcheck_status_secc));

        //重置T1
		OpenChaoJi_os_soft_timer_reset(&context->running_data.b->self_check.T1);
    }
	/*
	  自检成功:粘连检测、短路检测、绝缘检测完成，并且检测结果都是成功则自检成功，则
	  发送“充电机自检结果_成功”报文后，发送“充电机阶段确认信息”报文，进入S3
	*/
	if ((self_check_inf.selfsta_adhesion == SELFSTA_ADHESION_END)
		&& (self_check_inf.selfsta_short == SELFSTA_SHORT_END)
		&& ((self_check_inf.selfsta_imd == SELFSTA_IMD_END)))
	{
		if ((self_check_inf.selfres_adhesion == SELFRES_ADHESION_SUCCESS)
			&& (self_check_inf.selfres_short == SELFRES_SHORT_SUCCESS)
			&& ((self_check_inf.selfres_imd == SELFRES_IMD_SUCCESS)))
		{
			//发送“充电机自检结果_成功”报文
		    context->running_data.b->self_check.selfcheck_result_secc.check_adhesion_result =
											((self_check_inf.selfres_adhesion == SELFRES_ADHESION_SUCCESS)? OPENCHAOJI_GBT27930_B_CHECK_RESULT_SUCCEED:OPENCHAOJI_GBT27930_B_CHECK_RESULT_FAILED);
			context->running_data.b->self_check.selfcheck_result_secc.check_insulation_result =
											((self_check_inf.selfres_imd == SELFRES_IMD_SUCCESS)? OPENCHAOJI_GBT27930_B_CHECK_RESULT_SUCCEED:OPENCHAOJI_GBT27930_B_CHECK_RESULT_FAILED);
			context->running_data.b->self_check.selfcheck_result_secc.check_short_circuit_result =
											((self_check_inf.selfres_short == SELFRES_SHORT_SUCCESS)? OPENCHAOJI_GBT27930_B_CHECK_RESULT_SUCCEED:OPENCHAOJI_GBT27930_B_CHECK_RESULT_FAILED);

            OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_FUNC_SELFCHECK_RESULT_SECC, (uint8_t *)(&context->running_data.b->self_check.selfcheck_result_secc), sizeof(context->running_data.b->self_check.selfcheck_result_secc));
            LOG_STATUS_CHANGE("[%d]Self Check S2 Checking Send Self Check Result: Success", context->tag);

			// 发送“充电机阶段确认信息”报文
            OpenChaoJi_gbt27930_b_secc_next_phase_info_send(context);
            LOG_STATUS_CHANGE("[%d]Self Check S2 Checking Send Phase Confirm", context->tag);

            // 进入S3
            LOG_STATUS_CHANGE("[%d]Self Check S2 Checking Checking -> S3 Confirm", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S3_PHASE_CONFIRM;
        }
	}

	/*
	  自检失败,粘连检测、短路检测、绝缘检测任一项检测失败则失败,发送
	  “充电机自检结果_失败”报文及“中止_自检失败”报文，进入S5
	*/
	if (((self_check_inf.selfsta_adhesion == SELFSTA_ADHESION_END) && (self_check_inf.selfres_adhesion == SELFRES_ADHESION_ERROR))
		||((self_check_inf.selfsta_short == SELFSTA_SHORT_END) && (self_check_inf.selfres_short == SELFRES_SHORT_ERROR))
		||((self_check_inf.selfsta_imd == SELFSTA_IMD_END) && (self_check_inf.selfres_imd == SELFRES_IMD_ERROR))
		)
	{
		//发送“充电机自检结果_失败”报文
		context->running_data.b->self_check.selfcheck_result_secc.check_adhesion_result =
											((self_check_inf.selfres_adhesion == SELFRES_ADHESION_SUCCESS)? OPENCHAOJI_GBT27930_B_CHECK_RESULT_SUCCEED:OPENCHAOJI_GBT27930_B_CHECK_RESULT_FAILED);
		context->running_data.b->self_check.selfcheck_result_secc.check_insulation_result =
											((self_check_inf.selfres_imd == SELFRES_ADHESION_SUCCESS)? OPENCHAOJI_GBT27930_B_CHECK_RESULT_SUCCEED:OPENCHAOJI_GBT27930_B_CHECK_RESULT_FAILED);
		context->running_data.b->self_check.selfcheck_result_secc.check_short_circuit_result =
											((self_check_inf.selfres_short == SELFRES_ADHESION_SUCCESS)? OPENCHAOJI_GBT27930_B_CHECK_RESULT_SUCCEED:OPENCHAOJI_GBT27930_B_CHECK_RESULT_FAILED);


		LOG_STATUS_CHANGE("Self Check S2 Checking adh=%d imd=%d short=%d",self_check_inf.selfres_adhesion,self_check_inf.selfres_imd,self_check_inf.selfres_short);

        OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_FUNC_SELFCHECK_RESULT_SECC, (uint8_t *)(&context->running_data.b->self_check.selfcheck_result_secc), sizeof(context->running_data.b->self_check.selfcheck_result_secc));
        LOG_STATUS_CHANGE("[%d]Self Check S2 Checking Send Self Check Result: Fail", context->tag);

		//发送“中止_自检失败”报文
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_SELFCHECK);
        LOG_STATUS_CHANGE("[%d]Self Check S2 Checking Send Stop Self Check: Fail", context->tag);

		//进入S5
        LOG_STATUS_CHANGE("[%d]Self Check S2 Checking -> S5 Fail", context->tag);
		return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S5_FAIL;
    }

	//Tc定时器到
	if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->self_check.Tc))
	{
        LOG_INFO("[%d]Self Check S2 Checking Tc Timeout", context->tag);
		// 发送“中止_系统自检超 时”报文，进人S5
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TIMEOUT_SELFCHECK);
        LOG_STATUS_CHANGE("[%d]Self Check S2 Checking Send Stop Self Check: Timeout", context->tag);

		LOG_STATUS_CHANGE("[%d]Self Check S2 Checking -> S5 Fail", context->tag);
		return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S5_FAIL;
    }

	//保持S2
    LOG_STATUS_LOOP("[%d]Self Check S2 Checking Keep", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S2_CHECKING;
}

// 27930 表G.5 S3 阶段确认过程
#define OpenChaoJi_gbt27930_b_secc_prev_selfcheck_s3_confirm      NULL
#define OpenChaoJi_gbt27930_b_secc_post_selfcheck_s3_confirm      NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_selfcheck_s3_confirm(struct OpenChaoJi_secc_context * context)
{
	//电子锁未锁止
	if (context->running_data.b->latchging_status_evcc_ok)
	{
		//发送“中止_电子锁锁止异常”报文，进入S5
		if (context->running_data.b->latchging_status_evcc.latching_status != OPENCHAOJI_GBT27930_B_LATCHING_STATUS_TYPE_LOCKED)
		{
            OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_SELFCHECK);
            LOG_STATUS_LOOP("[%d]Self Check S3 Confirm Send Stop Electronic Locking Abnormality", context->tag);

            LOG_STATUS_LOOP("[%d]Self Check S3 Confirm -> S5 Fail", context->tag);
			return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S5_FAIL;
        }
	}

	//T1定时器到
	if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->self_check.T1))
	{
		LOG_MSG_TIMEOUT("[%d]Self Check S3 Confirm T1 Timeout, Reset T1", context->tag);
		//发送“充电机 自检状态_检测结束”报文，保持S3
	    context->running_data.b->self_check.selfcheck_status_secc.check_adhesion_status = OPENCHAOJI_GBT27930_B_CHECK_TYPE_CHECK_FINISHED;
		context->running_data.b->self_check.selfcheck_status_secc.check_insulation_status = OPENCHAOJI_GBT27930_B_CHECK_TYPE_CHECK_FINISHED;
		context->running_data.b->self_check.selfcheck_status_secc.check_short_circuit_status = OPENCHAOJI_GBT27930_B_CHECK_TYPE_CHECK_FINISHED;

        OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_FUNC_SELFCHECK_STATUS_SECC, (uint8_t *)(&context->running_data.b->self_check.selfcheck_status_secc), sizeof(context->running_data.b->self_check.selfcheck_status_secc));
		LOG_MSG_TIMEOUT("[%d]Self Check S3 Confirm Send Self Check Status: Detection End", context->tag);;

        //重置T1
		OpenChaoJi_os_soft_timer_reset(&context->running_data.b->self_check.T1);
    }

	// 接收"车辆阶段确认"报文
	if (context->running_data.b->phase_ack_evcc_ok)
	{
	   // 确认成功
	   if (context->running_data.b->phase_ack_evcc.phase_ack == OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED)
	   {
		   LOG_STATUS_CHANGE("[%d]Self Check S3 Confirm -> S4 Success", context->tag);
		   return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S4_SUCCEED;
	   }
	   else
	   {
		   // 发送"中止_阶段确认失败"报文

           OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_PHASE);
		   LOG_STATUS_CHANGE("[%d]Self Check S3 Confirm Send Phase Confirm Fail", context->tag);

           // 进入S5
		   LOG_STATUS_CHANGE("[%d]Self Check S3 Confirm -> S5 Fail", context->tag);
		   return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S5_FAIL;
       }
	}

	//Tc定时器到
	if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->self_check.Tc))
	{
        LOG_STATUS_CHANGE("[%d]Self Check S3 Confirm Tc Timeout", context->tag);
		//发送“中止_系统自检超 时”报文，进人S5

        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TIMEOUT_SELFCHECK);
        LOG_STATUS_CHANGE("[%d]Self Check S3 Confirm Send Stop Self Check: Timeout", context->tag);

		LOG_STATUS_CHANGE("[%d]Self Check S3 Confirm -> S5 Fail", context->tag);
		return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S5_FAIL;
    }

	//保持s3
    LOG_STATUS_LOOP("[%d]Self Check S3 Confirm Keep", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S3_PHASE_CONFIRM;
}

// 27930 表G.5 S4 成功
#define OpenChaoJi_gbt27930_b_secc_prev_selfcheck_s4_succeed      NULL
#define OpenChaoJi_gbt27930_b_secc_post_selfcheck_s4_succeed      NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_selfcheck_s4_succeed(struct OpenChaoJi_secc_context * context)
{
	LOG_STATUS_LOOP("[%d]Self Check S4 Success", context->tag);

	//关闭Tc、T1定时器，进入下一个功能模块FDC
	OpenChaoJi_os_soft_timer_stop(&context->running_data.b->self_check.Tc);
	OpenChaoJi_os_soft_timer_stop(&context->running_data.b->self_check.T1);
    LOG_STATUS_LOOP("[%d]Self Check S4 Tc Stop", context->tag);
    LOG_STATUS_LOOP("[%d]Self Check S4 T1 Stop", context->tag);

    // 根据功能协商结果进入下一功能模块FDC
    return OpenChaoJi_gbt27930_b_secc_find_next_module_status(context);
}

// 27930 表G.5 S5 失败
#define OpenChaoJi_gbt27930_b_secc_prev_selfcheck_s5_failed      NULL
#define OpenChaoJi_gbt27930_b_secc_post_selfcheck_s5_failed      NULL
static int  OpenChaoJi_gbt27930_b_secc_loop_selfcheck_s5_failed(struct OpenChaoJi_secc_context * context)
{
    LOG_STATUS_LOOP("[%d]Self Check S5 Fail", context->tag);
	OpenChaoJi_secc_hal_selfcheck_request_stop(context->hal_handle);//自检停止

	//关闭Tc、T1定时器，如果功能协商结果中“服务统计”功能模块协商成功，则在阶段确认后进入服务统计功能模块FDC,否则退出充电过程
	OpenChaoJi_os_soft_timer_stop(&context->running_data.b->self_check.Tc);
	OpenChaoJi_os_soft_timer_stop(&context->running_data.b->self_check.T1);
    LOG_STATUS_LOOP("[%d]Self Check S5 Tc Stop", context->tag);
    LOG_STATUS_LOOP("[%d]Self Check S5 T1 Stop", context->tag);

	// 则在阶段确认后进入服务统计功能模块FDC,否则退出充电过程
    return OpenChaoJi_gbt27930_b_secc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_SELFCHECK);
}

const struct OpenChaoJi_secc_module_status c_sytem_b_secc_status_array_self_check[OPENCHAOJI_GBT27930_B_SECC_STATUS_SELF_CHECK_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S0_INIT,
        .name = "SelfCheck.S0.Init",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_selfcheck_s0_init,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_selfcheck_s0_init,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_selfcheck_s0_init,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S1_ELOCKED,
        .name = "SelfCheck.S1.Elocked",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_selfcheck_s1_elocked,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_selfcheck_s1_elocked,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_selfcheck_s1_elocked,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S2_CHECKING,
        .name = "SelfCheck.S2.Checking",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_selfcheck_s2_checking,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_selfcheck_s2_checking,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_selfcheck_s2_checking,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S3_PHASE_CONFIRM,
        .name = "SelfCheck.S3.PhaseConfirm",



        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_selfcheck_s3_confirm,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_selfcheck_s3_confirm,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_selfcheck_s3_confirm,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S4_SUCCEED,
        .name = "SelfCheck.S4.Succeed",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_selfcheck_s4_succeed,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_selfcheck_s4_succeed,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_selfcheck_s4_succeed,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S5_FAIL,
        .name = "SelfCheck.S5.Fail",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_selfcheck_s5_failed,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_selfcheck_s5_failed,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_selfcheck_s5_failed,
    },
};

const struct OpenChaoJi_secc_module c_gbt27930_b_secc_module_self_check =
{
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_SELFCHECK,
    .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_SELFCHECK,
    .fdc_type = OPENCHAOJI_GBT27930_B_FDC_SELFCHECK_GENERAL,

    .name ="SELFCHECK",
    .status_array = c_sytem_b_secc_status_array_self_check,
    .status_array_len = OPENCHAOJI_GBT27930_B_SECC_STATUS_SELF_CHECK_NUM,
};





/* -------------- 预充及能量传输 模块 鲁软 -------------- */
/* 充电模式能量传输 FDC=1 */
#define OpenChaoJi_gbt27930_b_secc_prev_charging_s0_init         NULL
#define OpenChaoJi_gbt27930_b_secc_post_charging_s0_init         NULL
// 初始化
static int  OpenChaoJi_gbt27930_b_secc_loop_charging_s0_init(struct OpenChaoJi_secc_context * context)
{
    // 初始化
    LOG_STATUS_PREV("[%d]Energy Charge S0 Init", context->tag);
    context->running_data.b->charging.charging_precharge_status = 0x00;
    // 打开TC
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.Tc, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_TC_SECC);
    LOG_STATUS_PREV("[%d]Energy Charge S0 Init Tc Start", context->tag);

    // 发送"充电机就绪状态_未就绪报文"报文
    LOG_STATUS_PREV("[%d]Energy Charge S0 Send Charge Ready", context->tag);
    context->running_data.b->charging.charging_ready_secc.ready_status = OPENCHAOJI_GBT27930_B_READY_TYPE_NOT_READY;// 状态未就绪
    OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_READY_SECC,(uint8_t *)(&context->running_data.b->charging.charging_ready_secc),sizeof(context->running_data.b->charging.charging_ready_secc));

    // 打开T1
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T1, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_READY_SECC);
    LOG_STATUS_PREV("[%d]Energy Charge S0 Init T1 Start", context->tag);

    // 进入S1
    LOG_STATUS_CHANGE("[%d]Energy Charge S0 To S1", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S1_WAIT_VEHICLE_READY;
}

#define OpenChaoJi_gbt27930_b_secc_prev_charging_s1_wait         NULL
#define OpenChaoJi_gbt27930_b_secc_post_charging_s1_wait         NULL

// 由于27930未定义停止流程, 故H2,H3, H4等异常处理流程均不能按照状态转换表跳转到S5/S7状态, 改为跳转到Stopping_fail阶段
// Stopping_fail阶段会在执行停止流程后, 根据功能协商结果确认是否进入服务统计或直接结束
// 所以H2/H3/H4等在此处仅需释放本地定时器等资源后跳转Stopping_fail即可

static int OpenChaoJi_gbt27930_b_secc_loop_charging_H1(struct OpenChaoJi_secc_context * context)
{
    LOG_STATUS_CHANGE("[%d]Energy Charge H1", context->tag);

    //关闭Tc T1 ，打开T2
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T1);
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_T2_SECC);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.Tc);

    // 发送"中止_充电机正常停止"报文
    return OpenChaoJi_gbt27930_b_secc_stop_normal(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TERM_NORMAL);
}

static int OpenChaoJi_gbt27930_b_secc_loop_charging_H2(struct OpenChaoJi_secc_context * context)
{
    LOG_STATUS_CHANGE("[%d]Energy Charge H2", context->tag);

    //故障停机 关闭Tc T1 ，打开T2
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T1);
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_T2_SECC);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.Tc);

    // 车端停止, SECC无需发送停止报文
    return OpenChaoJi_gbt27930_b_secc_stop_normal(context, 0, 0);
}

static int OpenChaoJi_gbt27930_b_secc_loop_charging_H3(struct OpenChaoJi_secc_context * context)
{
    LOG_STATUS_CHANGE("[%d]Energy Charge H3", context->tag);

    //故障停机 关闭Tc T1 ，打开T2
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T1);
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_T2_SECC);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.Tc);

    // 发送"中止_预充超时"报文
    return OpenChaoJi_gbt27930_b_secc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TIMEOUT_ENERGY);
}

static int OpenChaoJi_gbt27930_b_secc_loop_charging_H4(struct OpenChaoJi_secc_context * context)
{
    LOG_STATUS_CHANGE("[%d]Energy Charge H4", context->tag);

    //故障停机 关闭Tc T1 ，打开T2
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T1);
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_T2_SECC);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.Tc);

    // 发送"中止_车辆逻辑错误"报文
    return OpenChaoJi_gbt27930_b_secc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_ENERGY);
}

static int OpenChaoJi_gbt27930_b_secc_loop_charging_pre_charge(struct OpenChaoJi_secc_context * context)
{
    //获取接触器C1 C2电压
    OpenChaoJi_secc_hal_sampling_value(context->hal_handle, &context->running_data.b->charging.charging_secc_hal_samp);

    LOG_STATUS_LOOP("[%d] secc_in_voltage:%d \t secc_out_voltage:%d", context->tag, context->running_data.b->charging.charging_secc_hal_samp.voltage_in, context->running_data.b->charging.charging_secc_hal_samp.voltage_out);

    if(context->running_data.b->charging.charging_precharge_status == 0x00)
    {
        int charging_pre_deviation = 0;
        int evcc_voltage = 0;
        int secc_voltage = 0;
        // 计算电压偏差，单位为百分比
        evcc_voltage = context->running_data.b->charging.charging_ready_evcc.voltage;
        secc_voltage = context->running_data.b->charging.charging_secc_hal_samp.voltage_out;
    	LOG_DATA_NORMAL("[%d] evcc_out_voltage:%d \t secc_out_voltage:%d", context->tag,evcc_voltage,secc_voltage);

        if (evcc_voltage != 0) {
            //判断C1C2外侧电压与通信报文电池电压误差%5以内且在充电机正常工作电压范围
            charging_pre_deviation = (evcc_voltage - secc_voltage) * 100 / evcc_voltage;
            // 判断电压偏差是否在 ±5% 范围内 电池电压在正常范围
            if ((abs(charging_pre_deviation) <= 5)
                && (evcc_voltage < OpenChaoJi_secc_hal_power_module_get_max_voltage(context->hal_handle))
                && (evcc_voltage > OpenChaoJi_secc_hal_power_module_get_min_voltage(context->hal_handle)))
            {
                //设置模块电压
                OpenChaoJi_secc_hal_power_module_request_start(context->hal_handle
                    , (evcc_voltage - 50)
                    , OpenChaoJi_secc_hal_power_module_get_min_current(context->hal_handle)
                );

                context->running_data.b->charging.charging_precharge_status = 0x01;
				LOG_STATUS_CHANGE("[%d] PreCharge %dV", context->tag, context->running_data.b->charging.charging_ready_evcc.voltage - 5);
            }
        }
    }else if(context->running_data.b->charging.charging_precharge_status == 0x01)
    {
        // 确认模块升压到跟外侧电池电压差距小于10V
        if(context->running_data.b->charging.charging_secc_hal_samp.voltage_out <= (context->running_data.b->charging.charging_secc_hal_samp.voltage_in + 100))
        {
            //闭合C1 C2
            OpenChaoJi_secc_hal_gbt_close_dc_relay(context->hal_handle, 1);
            context->running_data.b->charging.charging_precharge_status = 0x02;
			LOG_STATUS_CHANGE("[%d] CloseC1C2", context->tag);
        }
    }else if(context->running_data.b->charging.charging_precharge_status == 0x02)
    {
        if(OpenChaoJi_secc_hal_get_status_dc_relay(context->hal_handle) == OPENCHAOJI_SECC_HAL_DC_RELAY_C1C2_ALL_CLOSE) //C1 C2闭合
        {
            context->running_data.b->charging.charging_precharge_status = 0x03;
			LOG_STATUS_CHANGE("[%d] C1C2 Closed", context->tag);
        }
    }else
    {
        LOG_ERR("[%d]Energy Charge Pre Charge State [%d] UNKNOW", context->tag, context->running_data.b->charging.charging_precharge_status);
    }
    return context->running_data.b->charging.charging_precharge_status;
}

static int OpenChaoJi_gbt27930_b_secc_loop_charging_s1_wait(struct OpenChaoJi_secc_context * context)
{
    // 接收"车辆就绪状态"报文
    if (context->running_data.b->charging.charging_ready_evcc_ok)
    {
        LOG_DATA_CHANGE("[%d]Energy Charge S1 Recv Vehicle Ready", context->tag);
        if(context->running_data.b->charging.charging_ready_evcc.ready_status == OPENCHAOJI_GBT27930_B_READY_TYPE_READY)
        {
            // 由于后续状态中需要判断evcc是否发送Not Ready来停止充电, 这里需要清除标识, 用于触发后续接收判断流程
            context->running_data.b->charging.charging_ready_evcc_ok = 0;

            // 进入S2
            LOG_STATUS_CHANGE("[%d]Energy Charge S1 To S2", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S2_PRECHARGE;
        }
    }

    // Tc定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->charging.Tc))
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S1 Tc Timeout", context->tag);
        return OpenChaoJi_gbt27930_b_secc_loop_charging_H3(context);
    }

    // T1定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->charging.T1))
    {
        LOG_MSG_TIMEOUT("[%d]Energy Charge S1 T1 Timeout", context->tag);

        //发送充电机就绪_未就绪报文，保持S1
        context->running_data.b->charging.charging_ready_secc.ready_status = OPENCHAOJI_GBT27930_B_READY_TYPE_NOT_READY;//未就绪
        OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_READY_SECC,(uint8_t *)(&context->running_data.b->charging.charging_ready_secc),sizeof(context->running_data.b->charging.charging_ready_secc));

        //T1 reset
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T1, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_READY_SECC);
    }

    if(!context->app_permit_charge)// 充电机主动中止
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S1 SECC SIDE Stop", context->tag);
        return OpenChaoJi_gbt27930_b_secc_loop_charging_H1(context);
    }

    //接收车辆中止报文
    if(context->running_data.b->stop_info_evcc_ok)
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S1 EVCC SIDE Stop", context->tag);
        return OpenChaoJi_gbt27930_b_secc_loop_charging_H2(context);
    }

    // S1 LOOP
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S1_WAIT_VEHICLE_READY;
}

#define OpenChaoJi_gbt27930_b_secc_prev_charging_s2_pre         NULL
#define OpenChaoJi_gbt27930_b_secc_post_charging_s2_pre         NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_charging_s2_pre(struct OpenChaoJi_secc_context * context)
{
    // 接收"车辆就绪状态"报文
    if (context->running_data.b->charging.charging_ready_evcc_ok)
    {
        // 本状态中需要判断evcc是否发送Not Ready来停止充电, 这里需要清除标识, 用于后续再次触发接收判断流程
        context->running_data.b->charging.charging_ready_evcc_ok = 0;

        LOG_DATA_NORMAL("[%d]Energy Charge S2 Check if Vehicle not ready", context->tag);
        if(context->running_data.b->charging.charging_ready_evcc.ready_status == OPENCHAOJI_GBT27930_B_READY_TYPE_NOT_READY)//未就绪
        {
            LOG_STATUS_CHANGE("[%d]Energy Charge S2 EVCC LOGIC ERROR", context->tag);
            return OpenChaoJi_gbt27930_b_secc_loop_charging_H4(context);
        }
    }

    // Tc定时器到  //预充超时
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->charging.Tc))
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S2 Tc Timeout", context->tag);

        return OpenChaoJi_gbt27930_b_secc_loop_charging_H3(context);
    }

    // T1定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->charging.T1))
    {
        LOG_MSG_TIMEOUT("[%d]Energy Charge S2 T1 Timeout, PreCharge not finished", context->tag);
        //发送充电机就绪_未就绪报文，保持S2
        context->running_data.b->charging.charging_ready_secc.ready_status = OPENCHAOJI_GBT27930_B_READY_TYPE_NOT_READY;
        OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_READY_SECC,(uint8_t *)(&context->running_data.b->charging.charging_ready_secc),sizeof(context->running_data.b->charging.charging_ready_secc));

        OpenChaoJi_os_soft_timer_reset(&context->running_data.b->charging.T1);
    }

    // 判断预充是否完成
    if(OpenChaoJi_gbt27930_b_secc_loop_charging_pre_charge(context) == 0x03)
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S2 PreCharge Finish", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S3_CHARGER_READY;
    }

    //充电机主动中止
    if(!context->app_permit_charge)
    {
        //H1
        LOG_STATUS_CHANGE("[%d]Energy Charge S1 SECC SIDE Stop", context->tag);
        return OpenChaoJi_gbt27930_b_secc_loop_charging_H1(context);
    }

    //接收车辆中止报文
    if(context->running_data.b->stop_info_evcc_ok)
    {
        //H2
        LOG_STATUS_CHANGE("[%d]Energy Charge S1 EVCC SIDE Stop", context->tag);
        return OpenChaoJi_gbt27930_b_secc_loop_charging_H2(context);
    }
    // S2 LOOP
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S2_PRECHARGE;
}

#define OpenChaoJi_gbt27930_b_secc_prev_charging_s3_ready         NULL
#define OpenChaoJi_gbt27930_b_secc_post_charging_s3_ready         NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_charging_s3_ready(struct OpenChaoJi_secc_context * context)
{
    // 接收"车辆就绪状态"报文
    if (context->running_data.b->charging.charging_ready_evcc_ok)
    {
        // 本状态中需要判断evcc是否发送Not Ready来停止充电, 这里需要清除标识, 用于后续再次触发接收判断流程
        context->running_data.b->charging.charging_ready_evcc_ok = 0;

        LOG_DATA_NORMAL("[%d]Energy Charge S3 Check if Vehicle not ready", context->tag);
        if(context->running_data.b->charging.charging_ready_evcc.ready_status == OPENCHAOJI_GBT27930_B_READY_TYPE_NOT_READY)//未就绪
        {
            LOG_STATUS_CHANGE("[%d]Energy Charge S2 EVCC LOGIC ERROR", context->tag);
            return OpenChaoJi_gbt27930_b_secc_loop_charging_H4(context);
        }
    }

    // Tc定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->charging.Tc))
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S3 Tc Timeout", context->tag);
        return OpenChaoJi_gbt27930_b_secc_loop_charging_H3(context);
    }

    // T1定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->charging.T1))
    {
        LOG_MSG_TIMEOUT("[%d]Energy Charge S3 T1 Timeout", context->tag);

        //发送充电机就绪_就绪报文，保持S3
        context->running_data.b->charging.charging_ready_secc.ready_status = OPENCHAOJI_GBT27930_B_READY_TYPE_READY;
        OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_READY_SECC,(uint8_t *)(&context->running_data.b->charging.charging_ready_secc),sizeof(context->running_data.b->charging.charging_ready_secc));

        OpenChaoJi_os_soft_timer_reset(&context->running_data.b->charging.T1);
    }

    // 接收"车辆充电需求"报文
    if (context->running_data.b->charging.charging_requirement_evcc_ok)
    {
        //关闭T1 Tc 进入S4
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T1);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.Tc);

        LOG_STATUS_CHANGE("[%d]Energy Charge S3 T1 Tc Stop", context->tag);

        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S4_ENERGY_TRANSFER;
    }

    //充电机主动中止
    if(!context->app_permit_charge)
    {
        //H1
        LOG_STATUS_CHANGE("[%d]Energy Charge S1 SECC SIDE Stop", context->tag);
        return OpenChaoJi_gbt27930_b_secc_loop_charging_H1(context);
    }

    //接收车辆中止报文
    if(context->running_data.b->stop_info_evcc_ok)
    {
        //H2
        LOG_STATUS_CHANGE("[%d]Energy Charge S1 EVCC SIDE Stop", context->tag);
        return OpenChaoJi_gbt27930_b_secc_loop_charging_H2(context);
    }

    // 进入S3
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S3_CHARGER_READY;
}

#define OpenChaoJi_gbt27930_b_secc_prev_charging_s4_transfer         NULL
#define OpenChaoJi_gbt27930_b_secc_post_charging_s4_transfer         NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_charging_s4_transfer(struct OpenChaoJi_secc_context * context)
{
    // 接收"车辆充电需求"报文
    if (context->running_data.b->charging.charging_requirement_evcc_ok)
    {
        LOG_STATUS_LOOP("[%d]Energy Charge S4 Recv Vehicle Charge Requirement", context->tag);

        // 充电需求参数
        struct OpenChaoJi_secc_gbt27930_charging_requirement_parameter charging_requirement_evcc;
        charging_requirement_evcc.voltage = context->running_data.b->charging.charging_requirement_evcc.voltage;
        charging_requirement_evcc.current = context->running_data.b->charging.charging_requirement_evcc.current;
        charging_requirement_evcc.charge_mode = context->running_data.b->charging.charging_requirement_evcc.charge_mode;

        // 根据车辆需求要求App计算出实际需要下发模块的电压电流值
        OpenChaoJi_secc_app_get_power_output(context
            , &charging_requirement_evcc
            , &context->running_data.b->charging.volt_power_module
            , &context->running_data.b->charging.curr_power_module);

        // 调节输出
        OpenChaoJi_secc_hal_power_module_request_start(context->hal_handle
            , context->running_data.b->charging.volt_power_module
            , context->running_data.b->charging.curr_power_module);

    }

    // 检查当前输出能力输出能力变化
    if (OpenChaoJi_secc_app_check_dynamic_output(context, &context->running_data.b->charging.charging_ability_secc))
    {
        //发送"充电机动态输出能力"报文
        OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_ABILITY_SECC,(uint8_t *)(&context->running_data.b->charging.charging_ability_secc),sizeof(context->running_data.b->charging.charging_ability_secc));

        //保持S4
        LOG_STATUS_LOOP("[%d]Energy Charge S4 Loop", context->tag);
    }

    //充电机主动中止
    if (!context->app_permit_charge)
    {
        //H1
        LOG_STATUS_CHANGE("[%d]Energy Charge S1 SECC SIDE Stop", context->tag);
        return OpenChaoJi_gbt27930_b_secc_loop_charging_H1(context);
    }

    //接收车辆中止报文
    if(context->running_data.b->stop_info_evcc_ok)
    {
        //H2
        LOG_STATUS_CHANGE("[%d]Energy Charge S1 EVCC SIDE Stop", context->tag);
        return OpenChaoJi_gbt27930_b_secc_loop_charging_H2(context);
    }

    // 接收"车辆暂停充电报文" 暂未处理

    // 充电机主动暂停充电 暂未处理

    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S4_ENERGY_TRANSFER;
}

#define OpenChaoJi_gbt27930_b_secc_prev_charging_s5_confirm         NULL
#define OpenChaoJi_gbt27930_b_secc_post_charging_s5_confirm         NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_charging_s5_confirm(struct OpenChaoJi_secc_context * context)
{
    // 接收"车辆阶段确认"报文
    if (context->running_data.b->phase_ack_evcc_ok)
    {
        LOG_DATA_NORMAL("[%d]Energy Charge S5 Recv Vehicle Phase Confirm", context->tag);
        // 确认成功
        if (context->running_data.b->phase_ack_evcc.phase_ack == OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED)
        {
            LOG_STATUS_CHANGE("[%d]Energy Charge S5 To S6", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S6_FINISH;
        }
        else if(context->running_data.b->phase_ack_evcc.phase_ack == OPENCHAOJI_GBT27930_B_PHASE_ACK_FAILED)
        {
            // 发送"中止_阶段确认失败"报文
            LOG_STATUS_CHANGE("[%d]Energy Charge S5 Send Vehicle Phase Confirm Failed", context->tag);
            OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_PHASE);

            // 进入S7
            LOG_STATUS_CHANGE("[%d]Energy Charge S5 To S7", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S7_EXIT_CHARGING;
        }
    }

    // T2定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->charging.T2))
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S5 T2 Timeout", context->tag);
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_PHASE);

        // 进入S7
        LOG_STATUS_CHANGE("[%d]Energy Charge S5 To S7", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S7_EXIT_CHARGING;
    }

    LOG_STATUS_LOOP("[%d]Energy Charge S5 Loop", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S5_PHASE_CONFIRM;
}

#define OpenChaoJi_gbt27930_b_secc_prev_charging_s6_finish         NULL
#define OpenChaoJi_gbt27930_b_secc_post_charging_s6_finish         NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_charging_s6_finish(struct OpenChaoJi_secc_context * context)
{
    // 关闭Tc T1 T2
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T1);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T2);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.Tc);
    LOG_STATUS_CHANGE("[%d]Energy Charge S6 Stop Timer", context->tag);
    LOG_STATUS_CHANGE("[%d]Energy Charge S6 To Server Count", context->tag);

    // 进入服务统计功能模块;
    return  OpenChaoJi_gbt27930_b_secc_stop_normal(context, 0, 0);
}

#define OpenChaoJi_gbt27930_b_secc_prev_charging_s7_exit         NULL
#define OpenChaoJi_gbt27930_b_secc_post_charging_s7_exit         NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_charging_s7_exit(struct OpenChaoJi_secc_context * context)
{
    // 关闭Tc T1 T2
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T1);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T2);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.Tc);
    LOG_STATUS_CHANGE("[%d]Energy Charge S7 Stop Timer", context->tag);

    // 状态转换表此处要求直接停止流程, 但兼容18487, 此处依然走停止流程, 保证停止动作全部完成
    LOG_STATUS_CHANGE("[%d]Energy Charge S7 Exit", context->tag);
    return OpenChaoJi_gbt27930_b_secc_stop_normal(context, 0, 0);
}

const struct OpenChaoJi_secc_module_status c_sytem_b_secc_status_array_charging[OPENCHAOJI_GBT27930_B_SECC_STATUS_CHARGING_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S0_INIT,
        .name = "Charging.S0.Init",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_charging_s0_init,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_charging_s0_init,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_charging_s0_init,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S1_WAIT_VEHICLE_READY,
        .name = "Charging.S1.Wait",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_charging_s1_wait,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_charging_s1_wait,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_charging_s1_wait,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S2_PRECHARGE,
        .name = "Charging.S2.PreCharge",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_charging_s2_pre,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_charging_s2_pre,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_charging_s2_pre,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S3_CHARGER_READY,
        .name = "Charging.S3.Ready",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_charging_s3_ready,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_charging_s3_ready,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_charging_s3_ready,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S4_ENERGY_TRANSFER,
        .name = "Charging.S4.Transfer",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_charging_s4_transfer,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_charging_s4_transfer,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_charging_s4_transfer,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S5_PHASE_CONFIRM,
        .name = "Charging.S5.Confirm",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_charging_s5_confirm,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_charging_s5_confirm,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_charging_s5_confirm,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S6_FINISH,
        .name = "Charging.S6.Finish",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_charging_s6_finish,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_charging_s6_finish,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_charging_s6_finish,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S7_EXIT_CHARGING,
        .name = "Charging.S7.Exit",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_charging_s7_exit,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_charging_s7_exit,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_charging_s7_exit,
    },

};

const struct OpenChaoJi_secc_module c_gbt27930_b_secc_module_charging =
{
    .name = "Charging",
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_CHARGING,
    .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_ENERGY,
    .fdc_type = OPENCHAOJI_GBT27930_B_FDC_CHARGING,

    .status_array = c_sytem_b_secc_status_array_charging,
    .status_array_len = OPENCHAOJI_GBT27930_B_SECC_STATUS_CHARGING_NUM,
};

/* -------------- 服务统计停止中 模块 鲁软 -------------- */
//#define OpenChaoJi_gbt27930_b_secc_prev_statistics_stoping_s0_normal         NULL
#define	 OpenChaoJi_gbt27930_b_secc_post_statistics_stoping_s0_normal         NULL
void OpenChaoJi_gbt27930_b_secc_prev_statistics_stoping_s0_normal(struct OpenChaoJi_secc_context * context)
{
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_Tc, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_TC_SECC);
    context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state = 0x00;
}

static int  OpenChaoJi_gbt27930_b_secc_loop_statistics_stoping_s0_normal(struct OpenChaoJi_secc_context * context)
{
    if (context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state == 0x00)
    {
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T1, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T1_SECC);

        OpenChaoJi_secc_hal_power_module_request_stop(context->hal_handle); //停止充电模块
        LOG_STATUS_CHANGE("[%d]stop power module", context->tag);

        context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state = 0x01;
        LOG_STATUS_CHANGE("[%d]statistics_stoping_normol_secc_state 0x00->0x01", context->tag);
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state == 0x01)
    {
        OpenChaoJi_secc_hal_sampling_value(context->hal_handle,&context->running_data.b->charging.charging_secc_hal_samp);
        unsigned int power_current = OpenChaoJi_secc_hal_power_module_get_current(context->hal_handle);

        LOG_DATA_NORMAL("[%d]sample_current:%d, power_current:%d", context->tag, context->running_data.b->charging.charging_secc_hal_samp.current, power_current);

        //由于无法获取模块状态，目前只能以电流降至5A以下，认为模块停机完成。
        if ((context->running_data.b->charging.charging_secc_hal_samp.current <= 50) && (power_current <= 50))
        {
            LOG_STATUS_CHANGE("[%d]Current<=5A, Open Relay&S1", context->tag);

            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T1);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T2_SECC);

            OpenChaoJi_secc_hal_gbt_close_dc_relay(context->hal_handle,0);
            OpenChaoJi_secc_hal_gbt_b_close_s1(context->hal_handle,0);//断开S1 C1C2

            context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state = 0x02;
        	LOG_STATUS_CHANGE("[%d]statistics_stoping_normol_secc_state 0x01->0x02", context->tag);
        }
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state == 0x02)
    {
        //等待C1C2断开 S1断开
        if ((OpenChaoJi_secc_hal_get_status_dc_relay(context->hal_handle)) == OPENCHAOJI_SECC_HAL_DC_RELAY_C1C2_ALL_OPEN
        && (!OpenChaoJi_secc_hal_gbt_b_is_closed_s1(context->hal_handle)))
        {
            LOG_STATUS_CHANGE("[%d]C1C2&S1 opened", context->tag);
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T2);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T3, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T3_SECC);

            context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state = 0x03;
        	LOG_STATUS_CHANGE("[%d]statistics_stoping_normol_secc_state 0x02->0x03", context->tag);
        }
        else
        {
            OpenChaoJi_secc_hal_gbt_close_dc_relay(context->hal_handle,0);
            OpenChaoJi_secc_hal_gbt_b_close_s1(context->hal_handle,0);
        }
    }
    //等待C5C6断开
    else if(context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state == 0x03)
    {
        OpenChaoJi_secc_hal_sampling_value(context->hal_handle,&context->running_data.b->charging.charging_secc_hal_samp);
        LOG_DATA_NORMAL("[%d]voltage_out:%d", context->tag, context->running_data.b->charging.charging_secc_hal_samp.voltage_out);

        // 等待C5C6断开，方式为判断外侧电压为0，阈值取60V
        if (context->running_data.b->charging.charging_secc_hal_samp.voltage_out <= 600)
        {
            LOG_STATUS_CHANGE("[%d]Voltage_out<=60V, start vent", context->tag);

            //投泄放
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T3);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T4, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T4_SECC);

            OpenChaoJi_secc_hal_vent_request_start(context->hal_handle);
            context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state = 0x04;
        	LOG_STATUS_CHANGE("[%d]statistics_stoping_normol_secc_state 0x03->0x04", context->tag);
        }
    }
    //等待切泄放 此处建议起一个定时器将泄放投入时间控制在1s
    else if(context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state == 0x04)
    {
        //等待电压下降
        OpenChaoJi_secc_hal_sampling_value(context->hal_handle,&context->running_data.b->charging.charging_secc_hal_samp);
		LOG_DATA_NORMAL("[%d]voltage_in=%d voltage_out=%d current=%d", context->tag
            , context->running_data.b->charging.charging_secc_hal_samp.voltage_in
            , context->running_data.b->charging.charging_secc_hal_samp.voltage_out
            , context->running_data.b->charging.charging_secc_hal_samp.current);
        if (context->running_data.b->charging.charging_secc_hal_samp.voltage_in <= 600)
        {
            LOG_STATUS_CHANGE("[%d]voltage_in<=60V, vent OK", context->tag);

            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T4);
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_Tc);

            OpenChaoJi_secc_hal_vent_request_stop(context->hal_handle);

            context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state = 0x05;
        	LOG_STATUS_CHANGE("[%d]statistics_stoping_normol_secc_state 0x04->0x05", context->tag);
        }
    }
    else
    {
        context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state = 0x05;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Normal_T1))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T1);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T2_SECC);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_normol_secc_state [%02x]->0x02 ,The current drops to 5A timeout.", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state);

        context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state = 0x02;

        OpenChaoJi_secc_hal_gbt_close_dc_relay(context->hal_handle,0);
        OpenChaoJi_secc_hal_gbt_b_close_s1(context->hal_handle,0);//断开S1 C1C2
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Normal_T2))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T2);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T3, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T3_SECC);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_normol_secc_state [%02x]->0x03 ,C1/C2 or s1 disconnect timeout.", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state = 0x03;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Normal_T3))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T3);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T4, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T4_SECC);

        OpenChaoJi_secc_hal_vent_request_start(context->hal_handle);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_normol_secc_state [%02x]->0x04 ,C5/C6 disconnect timeout.", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state = 0x04;
    }

    //泄放电压过慢超时
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Normal_T4))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T4);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_Tc);

        OpenChaoJi_secc_hal_vent_request_stop(context->hal_handle);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_normol_secc_state [%02x]->0x05 ,Vent timeout.", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state = 0x05;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Normal_Tc))
    {
        LOG_STATUS_CHANGE("[%d] statistics_stoping_normol_secc_state [%02x]->0x05 ,normol stopping timeout.", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state = 0x05;
    }

    if(context->running_data.b->statistics_stoping.statistics_stoping_normol_secc_state == 0x05)
    {
        OpenChaoJi_secc_hal_gbt_close_dc_relay(context->hal_handle,0);
        OpenChaoJi_secc_hal_gbt_b_close_s1(context->hal_handle,0);//断开S1 C1C2
        OpenChaoJi_secc_hal_vent_request_stop(context->hal_handle); //切泄放

        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_Tc);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T1);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T2);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T3);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T4);

        //服务统计协商成功
        if (context->running_data.b->func_nego.func_support_evcc.fdc_statistics == OPENCHAOJI_GBT27930_B_FDC_STATISTICS)
        {
            // 发送“充电机阶段确认信息”报文
			OpenChaoJi_gbt27930_b_secc_phase_info_send(context,OPENCHAOJI_GBT27930_B_FC_TYPE_STATISTICS,OPENCHAOJI_GBT27930_B_FDC_STATISTICS);

            //打开T0
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.State_Tc, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_STATE_TC_SECC);

            LOG_STATUS_CHANGE("[%d]Stoping Charge S1 To S3", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S3_PHASE_CONFIRM;
        }
        else
        {
            //退出流程
            // 根据功能协商结果进入下一功能模块FDC
            LOG_STATUS_CHANGE("[%d]Stoping Charge S1 Exit", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_END_S0_FINISHING;
        }
    }

    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S0_NORMAL;
}

//#define OpenChaoJi_gbt27930_b_secc_prev_statistics_stoping_s1_fault         NULL
#define OpenChaoJi_gbt27930_b_secc_post_statistics_stoping_s1_fault         NULL

void OpenChaoJi_gbt27930_b_secc_prev_statistics_stoping_s1_fault(struct OpenChaoJi_secc_context * context)
{
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_Tc,OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_TC_SECC);
    context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state = 0;
}

static int OpenChaoJi_gbt27930_b_secc_loop_statistics_stoping_s1_fault(struct OpenChaoJi_secc_context *context)
{

    // 故障停机
    // 此处开定时器Tout 时间5s防止停机失败。执行操作为强制将停机状态转为停机完成，关所有开关。
    if (context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state == 0x00)
    {
        OpenChaoJi_secc_hal_sampling_value(context->hal_handle, &context->running_data.b->charging.charging_secc_hal_samp);
        unsigned int power_current = OpenChaoJi_secc_hal_power_module_get_current(context->hal_handle);
        if(power_current >= 2000)
        {
            //大于200A 延时至少100A/s
            unsigned int delay_fault_t1 = power_current;
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T1, delay_fault_t1);
        }
        else
        {
            //否则两秒
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T1, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T1_SECC);
        }
        // if (OpenChaoJi_secc_hal_power_module_get_min_voltage(context->hal_handle) < OpenChaoJi_secc_hal_power_module_get_voltage(context->hal_handle))
        // 由于无法获取模块状态，目前只能以输出电压是否有值作为判断模块有没有启动的条件。
        // {
        OpenChaoJi_secc_hal_power_module_request_stop(context->hal_handle); //停止充电模块
        // }
        LOG_STATUS_CHANGE("[%d]stop power module", context->tag);
        context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state = 0x01;
        LOG_STATUS_CHANGE("[%d]statistics_stoping_fault_secc_state 0x00->0x01", context->tag);
    }
    else if (context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state == 0x01)
    {
        // 等待电流下降
        OpenChaoJi_secc_hal_sampling_value(context->hal_handle, &context->running_data.b->charging.charging_secc_hal_samp);
        unsigned int power_current = OpenChaoJi_secc_hal_power_module_get_current(context->hal_handle);

        LOG_DATA_NORMAL("[%d]sample_current:%d, power_current:%d", context->tag, context->running_data.b->charging.charging_secc_hal_samp.current, power_current);
        if ((context->running_data.b->charging.charging_secc_hal_samp.current <= 50)
            && (OpenChaoJi_secc_hal_power_module_get_current(context->hal_handle) <= 50))
        {
            LOG_STATUS_CHANGE("[%d]Current<=5A, Open Relay&S1", context->tag);

            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T1);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T2_SECC);

            OpenChaoJi_secc_hal_gbt_close_dc_relay(context->hal_handle, 0);
            OpenChaoJi_secc_hal_gbt_b_close_s1(context->hal_handle, 0);//断开S1 C1C2
            context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state = 0x02;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_fault_secc_state 0x01->0x02", context->tag);
        }
    }
    else if (context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state == 0x02)
    {
        // 等待C1C2断开 S1断开
        if ((OpenChaoJi_secc_hal_get_status_dc_relay(context->hal_handle) == OPENCHAOJI_SECC_HAL_DC_RELAY_C1C2_ALL_OPEN)
            && (!OpenChaoJi_secc_hal_gbt_b_is_closed_s1(context->hal_handle)))
        {
            LOG_STATUS_CHANGE("[%d]C1C2&S1 opened", context->tag);
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T2);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T3, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T3_SECC);
            context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state = 0x03;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_fault_secc_state 0x02->0x03", context->tag);
        }
        else
        {
            OpenChaoJi_secc_hal_gbt_close_dc_relay(context->hal_handle,0);
            OpenChaoJi_secc_hal_gbt_b_close_s1(context->hal_handle,0);
        }
    }
    else if (context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state == 0x03)
    {
        // 等待C5C6断开判断接口电压
        OpenChaoJi_secc_hal_sampling_value(context->hal_handle, &context->running_data.b->charging.charging_secc_hal_samp);
        LOG_DATA_NORMAL("[%d]voltage_out:%d", context->tag, context->running_data.b->charging.charging_secc_hal_samp.voltage_out);

        // 等待C5C6断开，方式为判断外侧电压为0，阈值取60V
        if (context->running_data.b->charging.charging_secc_hal_samp.voltage_out <= 600) // 等待C5C6断开，方式为判断外侧电压为0，阈值取60V
        {
            LOG_STATUS_CHANGE("[%d]Voltage_out<=60V, start vent", context->tag);

            // 投泄放
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T3);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T4, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T4_SECC);

            OpenChaoJi_secc_hal_vent_request_start(context->hal_handle); // 投泄放
            // 为保证安全，此处建议开定时器将泄放投入时间强制设为1s 定时器时间1s 操作为将state置为4，并且切泄放。
            context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state = 0x04;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_fault_secc_state 0x03->0x04", context->tag);
        }
    }
    else if (context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state == 0x04)
    {
        // 判断电压泄放成功
        OpenChaoJi_secc_hal_sampling_value(context->hal_handle, &context->running_data.b->charging.charging_secc_hal_samp);
        LOG_DATA_NORMAL("[%d]voltage_in=%d voltage_out=%d current=%d", context->tag
            , context->running_data.b->charging.charging_secc_hal_samp.voltage_in
            , context->running_data.b->charging.charging_secc_hal_samp.voltage_out
            , context->running_data.b->charging.charging_secc_hal_samp.current);
        if (context->running_data.b->charging.charging_secc_hal_samp.voltage_in <= 600)
        {
            LOG_STATUS_CHANGE("[%d]voltage_in<=60V, vent OK", context->tag);
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T4);
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_Tc);

            OpenChaoJi_secc_hal_vent_request_stop(context->hal_handle);
            context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state = 0x05;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_fault_secc_state 0x04->0x05", context->tag);
        }
    }
    else
    {
        context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state = 0x05;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Fault_T1))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T1);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T2_SECC);
        LOG_STATUS_CHANGE("[%d] statistics_stoping_fault_secc_state [0x%02x]->0x02 because T1 The current drops to 5A timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state = 0x02;

        OpenChaoJi_secc_hal_gbt_close_dc_relay(context->hal_handle, 0);
        OpenChaoJi_secc_hal_gbt_b_close_s1(context->hal_handle, 0); // 断开S1 C1C2

    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Fault_T2))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T2);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T3, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T3_SECC);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_fault_secc_state [0x%02x]->0x03 because T2 C1/C2 or s1 disconnect timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state = 0x03;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Fault_T3))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T3);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T4, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T4_SECC);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_fault_secc_state [0x%02x]->0x04 because T3 C5/C6 disconnect timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state);

        OpenChaoJi_secc_hal_vent_request_start(context->hal_handle);
        context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state = 0x04;
    }

    // 泄放电压过慢超时
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Fault_T4))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T4);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_Tc);

        OpenChaoJi_secc_hal_vent_request_stop(context->hal_handle);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_fault_secc_state [0x%02x]->0x05 because T4 Vent timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state = 0x05;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Fault_Tc))
    {
        LOG_STATUS_CHANGE("[%d] statistics_stoping_fault_secc_state [0x%02x]->0x05 because Tc fail stopping timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state = 0x05;
    }

    if(context->running_data.b->statistics_stoping.statistics_stoping_fault_secc_state == 0x05)
    {
        OpenChaoJi_secc_hal_gbt_close_dc_relay(context->hal_handle, 0);
        OpenChaoJi_secc_hal_gbt_b_close_s1(context->hal_handle, 0); // 断开S1 C1C2
        OpenChaoJi_secc_hal_vent_request_stop(context->hal_handle);     // 切泄放

        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_Tc);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T1);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T2);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T3);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T4);
        // 服务统计协商成功
        if (context->running_data.b->func_nego.func_support_evcc.fdc_statistics == OPENCHAOJI_GBT27930_B_FDC_SUPPORT_TYPE_SUPPORT)
        {
            // 发送“充电机阶段确认信息”报文
            OpenChaoJi_gbt27930_b_secc_next_phase_info_send(context);

            // 打开T0
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.State_Tc, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_STATE_TC_SECC);

            LOG_STATUS_CHANGE("[%d]Stoping Charge S1 To S3", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S3_PHASE_CONFIRM;
        }
        else
        {
            // 退出流程
            LOG_STATUS_CHANGE("[%d]Stoping Charge S1 Exit", context->tag);
            // 根据功能协商结果进入下一功能模块FDC
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_END_S0_FINISHING;
        }
    }

    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S1_FAULT;
}

#define OpenChaoJi_gbt27930_b_secc_post_statistics_stoping_s2_emrge         NULL
void OpenChaoJi_gbt27930_b_secc_prev_statistics_stoping_s2_emrge(struct OpenChaoJi_secc_context * context)
{
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_Tc, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_TC_SECC);
    context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state = 0x00;
}
static int  OpenChaoJi_gbt27930_b_secc_loop_statistics_stoping_s2_emrge(struct OpenChaoJi_secc_context * context)
{
    //紧急停机
    //此处开定时器Tout 时间2s防止停机失败。执行操作为强制将停机状态转为停机完成，打开所有开关。
    if(context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state == 0x00)
    {
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_T1, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_T1_SECC);
        OpenChaoJi_secc_hal_power_module_request_stop(context->hal_handle); //停止充电模块
        OpenChaoJi_secc_hal_gbt_b_close_s1(context->hal_handle,0);

        LOG_STATUS_CHANGE("[%d]stop power module", context->tag);
        context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state = 0x01;
        LOG_STATUS_CHANGE("[%d]statistics_stoping_emerg_secc_state 0x00->0x01", context->tag);
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state == 0x01)
    {
        // 通知立即采样
        OpenChaoJi_secc_hal_sampling_value(context->hal_handle,&context->running_data.b->charging.charging_secc_hal_samp);

        //以电流降至5A以下，认为模块停机完成。
        unsigned int power_current = OpenChaoJi_secc_hal_power_module_get_current(context->hal_handle);

        LOG_STATUS_CHANGE("[%d]sample_current:%d, power_current:%d", context->tag, context->running_data.b->charging.charging_secc_hal_samp.current, power_current);
        if ((context->running_data.b->charging.charging_secc_hal_samp.current <= 50)
            && (OpenChaoJi_secc_hal_power_module_get_current(context->hal_handle) <= 50))
        {
            LOG_STATUS_CHANGE("[%d]Current<=5A, Open Relay&S1", context->tag);

            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T1);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_T2_SECC);

            OpenChaoJi_secc_hal_gbt_close_dc_relay(context->hal_handle,0);
            OpenChaoJi_secc_hal_gbt_b_close_s1(context->hal_handle,0);

            context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state = 0x02;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_emerg_secc_state 0x01->0x02", context->tag);
        }
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state == 0x02)
    {
        //等待C1C2断开
        if ((OpenChaoJi_secc_hal_get_status_dc_relay(context->hal_handle) == OPENCHAOJI_SECC_HAL_DC_RELAY_C1C2_ALL_OPEN)
            && (!OpenChaoJi_secc_hal_gbt_b_is_closed_s1(context->hal_handle)))
        {
            LOG_STATUS_CHANGE("[%d]C1C2&S1 opened", context->tag);
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T2);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_T3, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_T3_SECC);
            context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state = 0x03;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_emerg_secc_state 0x02->0x03", context->tag);
        }
        else
        {
            OpenChaoJi_secc_hal_gbt_close_dc_relay(context->hal_handle,0);
            OpenChaoJi_secc_hal_gbt_b_close_s1(context->hal_handle,0);
        }

    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state == 0x03)
    {
         //等待C5C6断开判断接口电压
        OpenChaoJi_secc_hal_sampling_value(context->hal_handle,&context->running_data.b->charging.charging_secc_hal_samp);
        LOG_DATA_NORMAL("[%d]voltage_out:%d", context->tag, context->running_data.b->charging.charging_secc_hal_samp.voltage_out);

        if (context->running_data.b->charging.charging_secc_hal_samp.voltage_out <= 600) //等待C5C6断开，方式为判断外侧电压为0，阈值取60V
        {
            LOG_STATUS_CHANGE("[%d]Voltage_out<=60V, start vent", context->tag);
            //投泄放
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T3);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_T4, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_T4_SECC);

            OpenChaoJi_secc_hal_vent_request_start(context->hal_handle); //投泄放
          //为保证安全，此处建议开定时器将泄放投入时间强制设为1s 定时器时间1s 操作为将state置为4，并且切泄放。
            context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state = 0x04;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_emerg_secc_state 0x03->0x04", context->tag);
        }
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state == 0x04)
    {
        //判断电压泄放成功
        OpenChaoJi_secc_hal_sampling_value(context->hal_handle,&context->running_data.b->charging.charging_secc_hal_samp);
        LOG_STATUS_CHANGE("[%d]voltage_in=%d voltage_out=%d current=%d", context->tag
            , context->running_data.b->charging.charging_secc_hal_samp.voltage_in
            , context->running_data.b->charging.charging_secc_hal_samp.voltage_out
            , context->running_data.b->charging.charging_secc_hal_samp.current);
        if (context->running_data.b->charging.charging_secc_hal_samp.voltage_in <= 600)
        {
            LOG_STATUS_CHANGE("[%d]voltage_in<=60V, vent OK", context->tag);
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T4);
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_Tc);

            OpenChaoJi_secc_hal_vent_request_stop(context->hal_handle);
            context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state = 0x05;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_emerg_secc_state 0x04->0x05", context->tag);
        }
    }

    else
    {
        context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state = 0x05;
    }


    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Emrge_T1))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T1);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_T2_SECC);
        LOG_STATUS_CHANGE("[%d] statistics_stoping_emerg_secc_state [%02x]->0x02 because T1 The current drops to 5A timeout", context->tag,context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state = 0x02;

        OpenChaoJi_secc_hal_gbt_close_dc_relay(context->hal_handle,0);
        OpenChaoJi_secc_hal_gbt_b_close_s1(context->hal_handle,0);//断开S1 C1C2

    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Emrge_T2))
    {

        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T2);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_T3, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_T3_SECC);
        LOG_STATUS_CHANGE("[%d] statistics_stoping_emerg_secc_state [0x%02x]->0x03 because T2 C1/C2 disconnect  timeout", context->tag,context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state = 0x03;

    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Emrge_T3))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T3);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_T4, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_T4_SECC);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_emerg_secc_state [0x%02x]->0x04 because T3 timeout", context->tag,context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state);

        OpenChaoJi_secc_hal_vent_request_start(context->hal_handle);
        LOG_STATUS_CHANGE("[%d] statistics_stoping_emergency_secc_state [0x%02x]->0x04 ,C5/C6 disconnect timeout.", context->tag,context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state = 0x04;
    }

    //泄放电压过慢超时
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Emrge_T4))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T4);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_Tc);

        OpenChaoJi_secc_hal_vent_request_stop(context->hal_handle);
        LOG_STATUS_CHANGE("[%d] statistics_stoping_emerg_secc_state [%02x]->0x05 because T4 Vent timeout", context->tag,context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state = 0x05;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Emrge_Tc))
    {
        LOG_STATUS_CHANGE("[%d] statistics_stoping_emerg_secc_state [%02x]->0x05 because Tc Emergency stopping timeout", context->tag,context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state = 0x05;
    }

    if(context->running_data.b->statistics_stoping.statistics_stoping_emergency_secc_state == 0x05)
    {
        OpenChaoJi_secc_hal_gbt_close_dc_relay(context->hal_handle,0);
        OpenChaoJi_secc_hal_gbt_b_close_s1(context->hal_handle,0);//断开S1 C1C2
        OpenChaoJi_secc_hal_vent_request_stop(context->hal_handle); //切泄放

        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_Tc);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T1);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T2);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T3);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T4);
        //服务统计协商成功
        if(context->running_data.b->func_nego.func_support_evcc.fdc_statistics == OPENCHAOJI_GBT27930_B_FDC_SUPPORT_TYPE_SUPPORT)
        {
            // 发送“充电机阶段确认信息”报文
            OpenChaoJi_gbt27930_b_secc_next_phase_info_send(context);

            //打开T0
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.State_Tc, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_STATE_TC_SECC);
            LOG_STATUS_CHANGE("[%d]Stoping Charge S2 T0 Start", context->tag);
            // 进入S3
            LOG_STATUS_CHANGE("[%d]Stoping Charge S2 To S3", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S3_PHASE_CONFIRM;
        }else
        {
            //退出流程
            LOG_STATUS_CHANGE("[%d]Energy Charge S2 Exit", context->tag);
            //进入下一个功能模块;
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_END_S0_FINISHING;
        }
    }

    return  OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S2_EMRGE;
}

#define OpenChaoJi_gbt27930_b_secc_prev_statistics_stoping_s3_phase_confirm         NULL
#define OpenChaoJi_gbt27930_b_secc_post_statistics_stoping_s3_phase_confirm         NULL

static int  OpenChaoJi_gbt27930_b_secc_loop_statistics_stoping_s3_phase_confirm(struct OpenChaoJi_secc_context * context)
{
    // 接收"车辆阶段确认"报文
    if (context->running_data.b->phase_ack_evcc_ok)
    {
        LOG_DATA_CHANGE("[%d]Stoping Charge S3 Recv Vehicle Phase Confirm", context->tag);

        // 确认成功
        if (context->running_data.b->phase_ack_evcc.phase_ack == OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED)
        {
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.State_Tc);

            // 进入服务统计
            LOG_STATUS_CHANGE("[%d]Stoping Charge S3 To Statistics Charge S0", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STATISTICS_S0_INIT;
        }
        else if(context->running_data.b->phase_ack_evcc.phase_ack == OPENCHAOJI_GBT27930_B_PHASE_ACK_FAILED)
        {
            // 发送"中止_阶段确认失败"报文
            LOG_STATUS_CHANGE("[%d]Stoping Charge S3 Send Vehicle Phase Confirm Failed", context->tag);
            OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_PHASE);

            OpenChaoJi_os_soft_timer_is_stopped(&context->running_data.b->statistics_stoping.State_Tc);

            // 阶段确认失败退出
            LOG_STATUS_CHANGE("[%d]Stoping Charge S3 Exit", context->tag);
            return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_END_S0_FINISHING;
        }
    }
    // Tc定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.State_Tc))
    {
        // 确认失败
        LOG_STATUS_CHANGE("[%d]Stoping Charge S3 T0 Timeout", context->tag);
        // 发送"中止_阶段确认超时"报文
        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TIMEOUT_ENERGY);

        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.State_Tc);
        LOG_STATUS_CHANGE("[%d]Stoping Charge S3 Stop failed", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_END_S0_FINISHING;

    }
    return  OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S3_PHASE_CONFIRM;
}

const struct OpenChaoJi_secc_module_status c_sytem_b_secc_status_array_statistics_stoping[OPENCHAOJI_GBT27930_B_SECC_STATUS_STOPING_END_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S0_NORMAL,
        .name = "Stoping.S0.Normal",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_statistics_stoping_s0_normal,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_statistics_stoping_s0_normal,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_statistics_stoping_s0_normal,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S1_FAULT,
        .name = "Stoping.S1.Fault",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_statistics_stoping_s1_fault,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_statistics_stoping_s1_fault,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_statistics_stoping_s1_fault,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S2_EMRGE,
        .name = "Stoping.S2.Emrge",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_statistics_stoping_s2_emrge,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_statistics_stoping_s2_emrge,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_statistics_stoping_s2_emrge,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S3_PHASE_CONFIRM,
        .name = "Stoping.S3.PhaseConfirm",

        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_statistics_stoping_s3_phase_confirm,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_statistics_stoping_s3_phase_confirm,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_statistics_stoping_s3_phase_confirm,
    },

};
const struct OpenChaoJi_secc_module c_gbt27930_b_secc_module_statistics_stoping =
{
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_STATISTICS_STOPING,
    .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_SERVICE_STOPPING,
    .fdc_type = 1,
    .name = "STOPPING",
    .status_array = c_sytem_b_secc_status_array_statistics_stoping,
    .status_array_len = OPENCHAOJI_GBT27930_B_SECC_STATUS_STOPING_END_NUM,
};

/* -------------- 服务统计 模块 长园 -------------- */
#define OpenChaoJi_gbt27930_b_secc_prev_statistics_s0_init         NULL
#define OpenChaoJi_gbt27930_b_secc_post_statistics_s0_init         NULL
// static void OpenChaoJi_gbt27930_b_secc_prev_statistics_s0_init(struct OpenChaoJi_secc_context * context);
// static void OpenChaoJi_gbt27930_b_secc_post_statistics_s0_init(struct OpenChaoJi_secc_context * context);
static int  OpenChaoJi_gbt27930_b_secc_loop_statistics_s0_init(struct OpenChaoJi_secc_context * context)
{
    // 初始化
    LOG_STATUS_PREV("[%d]STATISTICS S0 init start", context->tag);

    // 打开Tc
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics.Tc, OPENCHAOJI_GBT27930_B_PID_TC_TIMEOUT_STATISTICS_SECC);
    LOG_STATUS_PREV("[%d]STATISTICS S0 Tc start", context->tag);

    // 发送"充电机统计信息"报文
    LOG_STATUS_PREV("[%d]STATISTICS S0 Send charger statistics packet", context->tag);
    OpenChaoJi_secc_app_get_charge_total_energy(context, &context->running_data.b->statistics.statistics_secc.charge_total_energy);
    OpenChaoJi_gbt27930_b_secc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_STATISTICS_SECC, (uint8_t *)(&context->running_data.b->statistics.statistics_secc), sizeof(context->running_data.b->statistics.statistics_secc));

    // 进入S1
    LOG_STATUS_CHANGE("[%d]STATISTICS S0 goto S1", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STATISTICS_S1_WAIT_EV_PACKET;
}

#define OpenChaoJi_gbt27930_b_secc_prev_statistics_s1_wait_ev_packet         NULL
#define OpenChaoJi_gbt27930_b_secc_post_statistics_s1_wait_ev_packet         NULL
// static void OpenChaoJi_gbt27930_b_secc_prev_statistics_s1_wait_ev_packet(struct OpenChaoJi_secc_context * context);
// static void OpenChaoJi_gbt27930_b_secc_post_statistics_s1_wait_ev_packet(struct OpenChaoJi_secc_context * context);
static int  OpenChaoJi_gbt27930_b_secc_loop_statistics_s1_wait_ev_packet(struct OpenChaoJi_secc_context * context)
{
    // 接收"车辆统计信息"报文
    if (context->running_data.b->statistics.statistics_evcc_ok)
    {
        // 进入S2
        LOG_STATUS_CHANGE("[%d]STATISTICS S1 Recv evcc statistics packet and goto S2", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STATISTICS_S2_RETURN;
    }

    // Tc定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics.Tc))
    {
        // 发送"中止_服务统计超时"报文
        LOG_STATUS_CHANGE("[%d]STATISTICS S1 Tc timeout and send stop info packet", context->tag);

        OpenChaoJi_gbt27930_b_secc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TIMEOUT_STATISTICS);

        // 进入S2
        LOG_STATUS_CHANGE("[%d]STATISTICS S1 goto S2", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STATISTICS_S2_RETURN;
    }

    // 未收到, 未超时, 继续等待
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STATISTICS_S1_WAIT_EV_PACKET;
}

#define OpenChaoJi_gbt27930_b_secc_prev_statistics_s2_return         NULL
#define OpenChaoJi_gbt27930_b_secc_post_statistics_s2_return         NULL
// static void OpenChaoJi_gbt27930_b_secc_prev_statistics_s2_return(struct OpenChaoJi_secc_context * context);
// static void OpenChaoJi_gbt27930_b_secc_post_statistics_s2_return(struct OpenChaoJi_secc_context * context);
static int  OpenChaoJi_gbt27930_b_secc_loop_statistics_s2_return(struct OpenChaoJi_secc_context * context)
{
    // 关闭Tc定时器
    LOG_STATUS_CHANGE("[%d]STATISTICS S2 Close Tc", context->tag);	// 需要提交
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics.Tc);

    // 退出充电过程
    LOG_STATUS_CHANGE("[%d]STATISTICS S2 Exit charging process", context->tag);
    return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_END_S0_FINISHING;
}

const struct OpenChaoJi_secc_module_status c_sytem_b_secc_status_array_statistics[OPENCHAOJI_GBT27930_B_SECC_STATUS_STATISTICS_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STATISTICS_S0_INIT,
        .name = "STATISTICS.S0.Init",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_statistics_s0_init,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_statistics_s0_init,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_statistics_s0_init,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STATISTICS_S1_WAIT_EV_PACKET,
        .name = "STATISTICS.S1.WaitEvPacket",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_statistics_s1_wait_ev_packet,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_statistics_s1_wait_ev_packet,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_statistics_s1_wait_ev_packet,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STATISTICS_S2_RETURN,
        .name = "STATISTICS.S2.Return",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_statistics_s2_return,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_statistics_s2_return,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_statistics_s2_return,
    },
};

const struct OpenChaoJi_secc_module c_gbt27930_b_secc_module_statistics =
{
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_STATISTICS,
    .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_STATISTICS,
    .fdc_type = OPENCHAOJI_GBT27930_B_FDC_STATISTICS,
    .status_array = c_sytem_b_secc_status_array_statistics,
    .status_array_len = OPENCHAOJI_GBT27930_B_SECC_STATUS_STATISTICS_NUM,
};




/* -------------- END 模块 星星 -------------- */

#define OpenChaoJi_gbt27930_b_secc_prev_end_s0_finishing         NULL
#define OpenChaoJi_gbt27930_b_secc_post_end_s0_finishing         NULL

static int OpenChaoJi_gbt27930_b_secc_loop_end_s0_finishing(struct OpenChaoJi_secc_context * context)
{
    LOG_STATUS_CHANGE("[%d]END S0", context->tag);

    context->app_permit_charge = 0;

    OpenChaoJi_gbt27930_b_secc_running_data_timer_reset(context);

	OpenChaoJi_secc_utility_session_stop(context->context_session);
    OpenChaoJi_secc_utility_pilot_reset(context->context_pilot);

	return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_END_S1_FINISHED;
}

#define OpenChaoJi_gbt27930_b_secc_prev_end_s1_finished         NULL
#define OpenChaoJi_gbt27930_b_secc_post_end_s1_finished         NULL

static int OpenChaoJi_gbt27930_b_secc_loop_end_s1_finished(struct OpenChaoJi_secc_context * context)
{
    LOG_STATUS_LOOP("[%d] END start s1", context->tag);

    // 拔枪进入IDLE
    if (!OpenChaoJi_secc_utility_pilot_is_evcc_connected(context->context_pilot))
    {
        LOG_STATUS_CHANGE("[%d] END S1: EVCC Disconnected", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_IDLE_S0_IDLE;
    }

    // 不拔枪启动第二次充电
    if (context->app_permit_charge)
    {
        LOG_STATUS_CHANGE("[%d] END S1: App Start Charge", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_IDLE_S0_IDLE;
    }

	return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_END_S1_FINISHED;
}

const struct OpenChaoJi_secc_module_status c_sytem_b_secc_status_array_end[OPENCHAOJI_GBT27930_B_SECC_STATUS_END_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_END_S0_FINISHING,
		.name = "End.S0.Finishing",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_end_s0_finishing,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_end_s0_finishing,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_end_s0_finishing,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_END_S1_FINISHED,
		.name = "End.S1.Finished",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_end_s1_finished,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_end_s1_finished,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_end_s1_finished,
    },
};

const struct OpenChaoJi_secc_module c_gbt27930_b_secc_module_end =
{
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_END,
    .fc_type = 2,
    .fdc_type = 1,
    .name = "END",
    .status_array = c_sytem_b_secc_status_array_end,
    .status_array_len = OPENCHAOJI_GBT27930_B_SECC_STATUS_END_NUM,
};

/* -------------- FAULT 模块 星星 -------------- */


#define OpenChaoJi_gbt27930_b_secc_prev_fault_s0_wait			NULL
#define OpenChaoJi_gbt27930_b_secc_post_fault_s0_wait			NULL

static int OpenChaoJi_gbt27930_b_secc_loop_fault_s0_wait(struct OpenChaoJi_secc_context * context)
{
    LOG_STATUS_CHANGE("[%d] Fault start s0", context->tag);

    context->app_permit_charge = 0;

    OpenChaoJi_gbt27930_b_secc_running_data_timer_reset(context);

	OpenChaoJi_secc_utility_session_stop(context->context_session);
    OpenChaoJi_secc_utility_pilot_reset(context->context_pilot);

	return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_END_S1_FINISHED;
}

#define OpenChaoJi_gbt27930_b_secc_prev_fault_s1_return			NULL
#define OpenChaoJi_gbt27930_b_secc_post_fault_s1_return			NULL

static int OpenChaoJi_gbt27930_b_secc_loop_fault_s1_return(struct OpenChaoJi_secc_context * context)
{
    LOG_STATUS_LOOP("[%d] Fault start s1", context->tag);

    // 拔枪进入IDLE
    if (!OpenChaoJi_secc_utility_pilot_is_evcc_connected(context->context_pilot))
    {
        LOG_STATUS_CHANGE("[%d] Fault S1: EVCC Disconnected", context->tag);
        return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_IDLE_S0_IDLE;
    }

	return OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_END_S1_FINISHED;
}

const struct OpenChaoJi_secc_module_status c_sytem_b_secc_status_array_fault[OPENCHAOJI_GBT27930_B_SECC_STATUS_FAULT_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FAULT_S0_WAIT,
		.name = "fault.s0",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_fault_s0_wait,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_fault_s0_wait,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_fault_s0_wait,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FAULT_S1_RETURN,
		.name = "fault.s1",
        .prev_func = OpenChaoJi_gbt27930_b_secc_prev_fault_s1_return,
        .post_func = OpenChaoJi_gbt27930_b_secc_post_fault_s1_return,
        .loop_func = OpenChaoJi_gbt27930_b_secc_loop_fault_s1_return,
    },
};

const struct OpenChaoJi_secc_module c_gbt27930_b_secc_module_fault =
{
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_FAULT,
    .fc_type = 3,
    .fdc_type = 1,
    .name = "FAULT",
    .status_array = c_sytem_b_secc_status_array_fault,
    .status_array_len = OPENCHAOJI_GBT27930_B_SECC_STATUS_FAULT_NUM,
};

/**
 * 通用子模块处理, 即跨越一般功能模块的一些全局功能的处理. 例如链路检测, 连接检测等
 * 由于连接检测需要快速响应, 厂家底层实现时可以考虑通过中断等方式触发后立即调用service方法来触发处理流程, 而不必等到定时处理
*/
static int OpenChaoJi_gbt27930_b_secc_sub_module_func(struct OpenChaoJi_secc_context * context)
{
    // TODO: 各种错误处理, 参考18487和27930
   if ((context->current_module_status_id >= OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S0_INIT)
   && (context->current_module_status_id < OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S0_NORMAL))
   {
       if (OpenChaoJi_secc_utility_session_is_connected(context->context_session) == OPENCHAOJI_SECC_UTILITY_SESSION_CONNECT_STATUS_DISCONNECTED)
       {
           LOG_ERR("[%d]LostConnection", context->tag);
           return OpenChaoJi_gbt27930_b_secc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TERM_FAILURE);
       }
   }

   if ((context->current_module_status_id >= OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S0_INIT)
   && (context->current_module_status_id < OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S0_NORMAL))
   {
       if (OpenChaoJi_secc_hal_is_emergency_pushed(context->hal_handle))
       {
           LOG_EMERG("[%d]EmergencyPushed", context->tag);
           return OpenChaoJi_gbt27930_b_secc_stop_emergency(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TERM_EMERGENCY);
       }
   }

    // TODO: 这个地方对预约的判断有问题, SESSION刚刚建立连接的时候, EVCC还没有Permit, 会导致3319行的pilot abnormal, 需讨论
    //导引异常判断
    // if (context->current_module_status_id >/*=*/ OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_TRIGGER_S1_SESSION
    //         && context->current_module_status_id < OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S0_INIT)
    // {
    //     #if(OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_RESERVE == CONFIG_YES)
    //     {
    //         if (OPENCHAOJI_MODULE_OF_ID(context->current_module_status_id) == OPENCHAOJI_GBT27930_B_MODULE_RESERVE)
    //         {
    //             enum OpenChaoJi_pilot_status_gbt18487_b status = OpenChaoJi_secc_utility_pilot_status_b(context->context_pilot);
    //             //预约阶段，存在S1动作，判断是否插枪和secc允许充电
    //             if ((OPENCHAOJI_PILOT_STATUS_GBT18487_B_C != status) && (OPENCHAOJI_PILOT_STATUS_GBT18487_B_B != status))
    //             {
    //                 LOG_CRIT("pilot abnormal");
    //                 return OpenChaoJi_gbt27930_b_secc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TERM_FAILURE);
    //             }
    //         }
    //         else if (!OpenChaoJi_secc_utility_pilot_b_is_evcc_permit_charge(context->context_pilot))
    //         {
    //             LOG_CRIT("pilot abnormal");
    //             return OpenChaoJi_gbt27930_b_secc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TERM_FAILURE);
    //         }
    //     }
    //     #else
    //     {
    //         if (!OpenChaoJi_secc_utility_pilot_b_is_evcc_permit_charge(context->context_pilot))
    //         {
    //             LOG_CRIT("pilot abnormal");
    //             return OpenChaoJi_gbt27930_b_secc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TERM_FAILURE);
    //         }
    //     }
    //     #endif
    // }

   if (context->current_module_status_id >= OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_SELF_CHECK_S2_CHECKING\
           && context->current_module_status_id < OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_STOPING_S0_NORMAL)
   {
       if (!OpenChaoJi_secc_utility_pilot_b_is_all_permit_charge(context->context_pilot))
       {
           LOG_CRIT("[%d]pilot Emergency", context->tag);
           return OpenChaoJi_gbt27930_b_secc_stop_emergency(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TERM_EMERGENCY);
       }
   }

    if (context->current_module_status_id >= OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_TRIGGER_S0_CONNECT
		&& context->current_module_status_id < OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_CHARGING_S0_INIT)	// 待讨论？能量传输各状态已有停机判断，sub_module改为在能量传输前判断
    {
        if (!context->app_permit_charge )
        {
            LOG_WARNING("[%d]AppStop", context->tag);
            return OpenChaoJi_gbt27930_b_secc_stop_normal(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TERM_NORMAL);
        }

		if (context->running_data.b->stop_info_evcc_ok)
        {
			LOG_WARNING("[%d]EVCCStop", context->tag);
            return OpenChaoJi_gbt27930_b_secc_stop_normal(context, 0, 0);
        }
    }

    /*公共报文周期发送+突传*/
    //接触器状态
    if (context->current_module_status_id >= OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_FUNC_NEGO_S0_INIT
		&& context->current_module_status_id < OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_END_S0_FINISHING)
    {
        /*启动公共报文定时器*/
        if (OpenChaoJi_os_soft_timer_is_stopped(&context->running_data.b->relay_status_secc_T1))
        {
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->relay_status_secc_T1,OPENCHAOJI_GBT27930_B_PID_TIMELOOP_RELAY_STATUS_SECC);
            LOG_INFO("[%d]Nego S0 C1C2 T1 start", context->tag);
        }

        unsigned char hal_relay_status = OpenChaoJi_secc_hal_get_status_dc_relay(context->hal_handle);
        if ((hal_relay_status != context->running_data.b->hal_relay_status_secc)
        || (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->relay_status_secc_T1)))
        {
            context->running_data.b->hal_relay_status_secc = hal_relay_status;
            OpenChaoJi_gbt27930_b_secc_relay_info_send(context, hal_relay_status);
        }
    }

    return context->current_module_status_id;
}

/**
 * 收发数据的通用处理方法
 * 收是在执行所有system操作前统一执行, 用于同步对端状态
 * 发是在执行所有system后统一执行, 用于把本方状态同步给对端
*/
void OpenChaoJi_gbt27930_b_secc_data_read_func(struct OpenChaoJi_secc_context * context)
{
    // 先把对端数据都收过来
    OpenChaoJi_secc_utility_session_service_try_recv(context->context_session);

    // 读空缓冲区, 解析到system数据处理区
    struct OpenChaoJi_utility_data_buff_recv_data recv_data;
    while (OpenChaoJi_secc_utility_session_data_read(context->context_session, &recv_data) == 0)
    {
        OpenChaoJi_gbt27930_b_secc_parse_data(context, &recv_data);
        if (!recv_data.recv_data.src_free)
        {
            OpenChaoJi_os_free(recv_data.recv_data.data);
        }
    }
}

void OpenChaoJi_gbt27930_b_secc_data_write_func(struct OpenChaoJi_secc_context * context)
{
    OpenChaoJi_secc_utility_session_service_try_send(context->context_session);
}

/**
 * 启停充电/获取充电等方法, 供App调用
*/
int OpenChaoJi_gbt27930_b_secc_app_start_func(struct OpenChaoJi_secc_context * context, struct OpenChaoJi_secc_app_start_parameter * app_start_parameter)
{
    LOG_ALERT("[%d]secc_app_start_func", context->tag);

    context->running_data.b->app_start_parameter = *app_start_parameter;
    context->app_permit_charge = 1;

    return 0;
}

int OpenChaoJi_gbt27930_b_secc_app_stop_func(struct OpenChaoJi_secc_context * context)
{
    LOG_ALERT("[%d]secc_app_stop_func", context->tag);

    context->app_permit_charge = 0;

    return 0;
}

int  OpenChaoJi_gbt27930_b_secc_app_get_status_func(struct OpenChaoJi_secc_context * context, struct OpenChaoJi_secc_context_status * status)
{
	status->current_module_status_id = context->current_module_status_id;
	status->demand_current = context->running_data.b->charging.charging_requirement_evcc.current;
	status->demand_voltage = context->running_data.b->charging.charging_requirement_evcc.voltage;
	status->soc = context->running_data.b->charging.charging_info_basic_evcc.soc;
	status->remain_time = context->running_data.b->charging.charging_info_basic_evcc.left_time;
	memcpy(status->evin, context->running_data.b->auth_evin.evin_param_evcc.evin, 17);
    status->precharge_status = context->running_data.b->charging.charging_precharge_status;
    return 0;
}

int OpenChaoJi_secc_create_system_gbt27930_b(struct OpenChaoJi_secc_context * context)
{
    /* 注册secc系统, 生成secc系统模块状态表 */
    context->secc_gbt27930_system = OpenChaoJi_os_malloc(sizeof(struct OpenChaoJi_secc_gbt27930_system));
    if (context->secc_gbt27930_system == NULL)
    {
        goto FAILED_CREATE;
    }
	memset(context->secc_gbt27930_system, 0x00, sizeof(struct OpenChaoJi_secc_gbt27930_system));

    context->secc_gbt27930_system->module_array = OpenChaoJi_os_malloc(OPENCHAOJI_GBT27930_B_MODULE_NUM * sizeof(struct OpenChaoJi_secc_module *));
    if (context->secc_gbt27930_system->module_array == NULL)
    {
        goto FAILED_CREATE;
    }
	memset(context->secc_gbt27930_system->module_array, 0x00, OPENCHAOJI_GBT27930_B_MODULE_NUM * sizeof(struct OpenChaoJi_secc_module *));
	context->secc_gbt27930_system->module_array_len = OPENCHAOJI_GBT27930_B_MODULE_NUM;

    /* -------------- IDLE 模块 特来电 -------------- */
    context->secc_gbt27930_system->module_array[OPENCHAOJI_GBT27930_B_MODULE_IDLE]          = &c_gbt27930_b_secc_module_idle;
    /* -------------- Trigger 模块 特来电 -------------- */
    context->secc_gbt27930_system->module_array[OPENCHAOJI_GBT27930_B_MODULE_TRIGGER]       = &c_gbt27930_b_secc_module_trigger;
    /* -------------- 功能协商 模块 嘉盛 -------------- */
    context->secc_gbt27930_system->module_array[OPENCHAOJI_GBT27930_B_MODULE_FUNC_NEGO]     = &c_gbt27930_b_secc_module_func_nego;
    /* -------------- 参数配置 模块 嘉盛 -------------- */
    context->secc_gbt27930_system->module_array[OPENCHAOJI_GBT27930_B_MODULE_PARAM_CONFIG]  = &c_gbt27930_b_secc_module_param_config;
    /* -------------- 授权(RFID) 模块 鲁软 -------------- */
    context->secc_gbt27930_system->module_array[OPENCHAOJI_GBT27930_B_MODULE_AUTH_RFID]     = &c_gbt27930_b_secc_module_auth_rfid;
    /* -------------- 授权(EVIN) 模块 鲁软 -------------- */
    context->secc_gbt27930_system->module_array[OPENCHAOJI_GBT27930_B_MODULE_AUTH_EVIN]     = &c_gbt27930_b_secc_module_auth_evin;
    /* -------------- 预约 模块 (暂空) -------------- */
    context->secc_gbt27930_system->module_array[OPENCHAOJI_GBT27930_B_MODULE_RESERVE]       = NULL;
    /* -------------- 系统自检 模块 领充 -------------- */
    context->secc_gbt27930_system->module_array[OPENCHAOJI_GBT27930_B_MODULE_SELFCHECK]     = &c_gbt27930_b_secc_module_self_check;
    /* -------------- 预充及能量传输 模块 鲁软 -------------- */
	context->secc_gbt27930_system->module_array[OPENCHAOJI_GBT27930_B_MODULE_CHARGING]      = &c_gbt27930_b_secc_module_charging;
    /* -------------- 服务统计停止中 模块 鲁软 -------------- */
    context->secc_gbt27930_system->module_array[OPENCHAOJI_GBT27930_B_MODULE_STATISTICS_STOPING] = &c_gbt27930_b_secc_module_statistics_stoping;
    /* -------------- 服务统计 模块 长园 -------------- */
    context->secc_gbt27930_system->module_array[OPENCHAOJI_GBT27930_B_MODULE_STATISTICS]    = &c_gbt27930_b_secc_module_statistics;
    /* -------------- END 模块 星星 -------------- */
	context->secc_gbt27930_system->module_array[OPENCHAOJI_GBT27930_B_MODULE_END]           = &c_gbt27930_b_secc_module_end;
    /* -------------- FAULT 模块 星星 -------------- */
	context->secc_gbt27930_system->module_array[OPENCHAOJI_GBT27930_B_MODULE_FAULT]         = &c_gbt27930_b_secc_module_fault;
    /* -------------- 通用功能 鲁软 -------------- */
    context->secc_gbt27930_system->sub_module_func      = OpenChaoJi_gbt27930_b_secc_sub_module_func;
    context->secc_gbt27930_system->data_read_func       = OpenChaoJi_gbt27930_b_secc_data_read_func;
    context->secc_gbt27930_system->data_write_func      = OpenChaoJi_gbt27930_b_secc_data_write_func;
    context->secc_gbt27930_system->app_start_func       = OpenChaoJi_gbt27930_b_secc_app_start_func;
    context->secc_gbt27930_system->app_stop_func        = OpenChaoJi_gbt27930_b_secc_app_stop_func;
    context->secc_gbt27930_system->app_get_status_func  = OpenChaoJi_gbt27930_b_secc_app_get_status_func;

    /* 创建运行时数据 */
    context->running_data.b = OpenChaoJi_os_malloc(sizeof(struct OpenChaoJi_secc_gbt27930_b_data));
    if (context->running_data.b == NULL)
    {
        goto FAILED_CREATE;
    }
	// memset(context->running_data.b, 0x00, sizeof(struct OpenChaoJi_secc_gbt27930_b_data));

    OpenChaoJi_gbt27930_b_secc_running_data_reset(context);

    context->current_module_status_id = OPENCHAOJI_GBT27930_B_SECC_STATUS_ID_IDLE_S0_IDLE;
    context->current_status_ticks = OpenChaoJi_os_get_ticks();

    return 0;

FAILED_CREATE:

    OpenChaoJi_secc_destory_system_gbt27930_b(context);

    return -1;
}


/**
 * @brief: 销毁系统上下文中system相关
 * @param {OpenChaoJi_secc_context *} context 系统上下文指针
 * @return {*}
 */
void OpenChaoJi_secc_destory_system_gbt27930_b(struct OpenChaoJi_secc_context * context)
{
    if (context->secc_gbt27930_system != NULL)
    {
        if (context->secc_gbt27930_system->module_array == NULL)
        {
            OpenChaoJi_os_free(context->secc_gbt27930_system->module_array);
        }

        OpenChaoJi_os_free(context->secc_gbt27930_system);
    }

    if (context->running_data.b != NULL)
    {
        OpenChaoJi_os_free(context->running_data.b);
    }
}

/**********************************以下为B类系统报文解析函数*******************************************/
/**
 * @brief  解析接收报文
 *
 * @param  context 系统上下文指针，包含必要的环境信息。
 * @param  recv_data 接收的数据结构
 * @return 成功返回0，失败返回-1。
 */
int OpenChaoJi_gbt27930_b_secc_parse_data(struct OpenChaoJi_secc_context * context, struct OpenChaoJi_utility_data_buff_recv_data * recv_data)
{
	if(recv_data->tag.gbt.msg_type != OPENCHAOJI_GBT27930_SYSTEM_B_MSG)
	{
        LOG_ERR("Not MsgType GBT-B");
        goto PARSE_FAILED;
    }

    struct OpenChaoJi_gbt27930_b_msg msg;
    if (!OpenChaoJi_gbt27930_b_msg_decode(&msg, recv_data->recv_data.data, recv_data->recv_data.len))
    {
        goto PARSE_FAILED;
    }

    bool changed = false;
    switch(recv_data->recv_data.data[0])
    {
    case OPENCHAOJI_GBT27930_B_PGI_FUNC_NEGO_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_func_support_evcc(context->tag
            , &context->running_data.b->func_nego.func_support_evcc
            , &msg.msg.func_support_evcc
        );
        if (!context->running_data.b->func_nego.func_support_evcc_ok)
        {
            LOG_WARNING("[%d]func_support_evcc_ok", context->tag);
            context->running_data.b->func_nego.func_support_evcc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_PARAM_CONFIG_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_param_config_evcc(context->tag
            , &context->running_data.b->param_config.param_config_evcc
            , &msg.msg.param_config_evcc
        );
        if (!context->running_data.b->param_config.param_config_evcc_ok)
        {
            LOG_WARNING("[%d]param_config_evcc_ok", context->tag);
            context->running_data.b->param_config.param_config_evcc_ok = 1;
            changed = true;
        }
        break;

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_AUTH == CONFIG_YES)
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_RFID == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_AUTH_RFID_WAIT_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_auth_rfid_wait_evcc(context->tag
            , &context->running_data.b->auth_rfid.rfid_wait_evcc
            , &msg.msg.auth_rfid_wait_evcc
        );
        if (!context->running_data.b->auth_rfid.rfid_wait_evcc_ok)
        {
            LOG_WARNING("[%d]rfid_wait_evcc_ok", context->tag);
            context->running_data.b->auth_rfid.rfid_wait_evcc_ok = 1;
            changed = true;
        }
        break;
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_EVIN == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_AUTH_EVIN_PARAM_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_auth_evin_param_evcc(context->tag
            , &context->running_data.b->auth_evin.evin_param_evcc
            , &msg.msg.auth_evin_param_evcc
        );
        if (!context->running_data.b->auth_evin.evin_param_evcc_ok)
        {
            LOG_WARNING("[%d]evin_param_evcc_ok", context->tag);
            context->running_data.b->auth_evin.evin_param_evcc_ok = 1;
            changed = true;
        }
        break;
#endif
#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_RESERVE == CONFIG_YES)
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_RESERVE_EVCC == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_RESERVE_INFO_EVCC:
        // changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_reserve_info_evcc(context->tag
        //     , &context->running_data.b->reserve.reserve_info_evcc
        //     , &msg.msg.reserve_info_evcc
        // );
        // if (!context->running_data.b->reserve.reserve_info_evcc_ok)
        // {
        //     LOG_WARNING("[%d]reserve_info_evcc_ok", context->tag);
        //     context->running_data.b->reserve.reserve_info_evcc_ok = 1;
        //     changed = true;
        // }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_RESERVE_NEGO_EVCC:
        // changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_reserve_nego_evcc(context->tag
        //     , &context->running_data.b->reserve.reserve_nego_evcc
        //     , &msg.msg.reserve_nego_evcc
        // );
        // if (!context->running_data.b->reserve.reserve_nego_evcc_ok)
        // {
        //     LOG_WARNING("[%d]reserve_nego_evcc_ok", context->tag);
        //     context->running_data.b->reserve.reserve_nego_evcc_ok = 1;
        //     changed = true;
        // }
        break;
#endif
#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SELFCHECK == CONFIG_YES)
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SELFCHECK_GENERAL == CONFIG_YES)
#endif
#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SUPPLY == CONFIG_YES)
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SUPPLY_BASIC == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_SUPPLY_STATUS_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_supply_status_evcc(context->tag
            , &context->running_data.b->supply.supply_status_evcc
            , &msg.msg.supply_status_evcc
        );
        if (!context->running_data.b->supply.supply_status_evcc_ok)
        {
            LOG_WARNING("[%d]supply_status_evcc_ok", context->tag);
            context->running_data.b->supply.supply_status_evcc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_SUPPLY_REQUIREMENT_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_supply_requirement_evcc(context->tag
            , &context->running_data.b->supply.supply_requirement_evcc
            , &msg.msg.supply_requirement_evcc
        );
        if (!context->running_data.b->supply.supply_requirement_evcc_ok)
        {
            LOG_WARNING("[%d]supply_requirement_evcc_ok", context->tag);
            context->running_data.b->supply.supply_requirement_evcc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_SUPPLY_FINISH_EVCC:

        break;
#endif
#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_CHARGING == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_READY_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_charging_ready_evcc(context->tag
            , &context->running_data.b->charging.charging_ready_evcc
            , &msg.msg.charging_ready_evcc
        );
        if (!context->running_data.b->charging.charging_ready_evcc_ok)
        {
            LOG_WARNING("[%d]charging_ready_evcc_ok", context->tag);
            context->running_data.b->charging.charging_ready_evcc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_REQUIREMENT_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_charging_requirement_evcc(context->tag
            , &context->running_data.b->charging.charging_requirement_evcc
            , &msg.msg.charging_requirement_evcc
        );
        if (!context->running_data.b->charging.charging_requirement_evcc_ok)
        {
            LOG_WARNING("[%d]charging_requirement_evcc_ok", context->tag);
            context->running_data.b->charging.charging_requirement_evcc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_INFO_BASIC_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_charging_info_basic_evcc(context->tag
            , &context->running_data.b->charging.charging_info_basic_evcc
            , &msg.msg.charging_info_basic_evcc
        );
        if (!context->running_data.b->charging.charging_info_basic_evcc_ok)
        {
            LOG_WARNING("[%d]charging_info_basic_evcc_ok", context->tag);
            context->running_data.b->charging.charging_info_basic_evcc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_INFO_BATTERY_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_charging_info_battery_evcc(context->tag
            , &context->running_data.b->charging.charging_info_battery_evcc
            , &msg.msg.charging_info_battery_evcc
        );
        if (!context->running_data.b->charging.charging_info_battery_evcc_ok)
        {
            LOG_WARNING("[%d]charging_info_battery_evcc_ok", context->tag);
            context->running_data.b->charging.charging_info_battery_evcc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_PAUSE_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_charging_pause_evcc(context->tag
            , &context->running_data.b->charging.charging_pause_evcc
            , &msg.msg.charging_pause_evcc
        );
        if (!context->running_data.b->charging.charging_pause_evcc_ok)
        {
            LOG_WARNING("[%d]charging_pause_evcc_ok", context->tag);
            context->running_data.b->charging.charging_pause_evcc_ok = 1;
            changed = true;
        }
        break;
#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_DISCHARGING == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_DISCHARGING_READY_EVCC:

        break;
    case OPENCHAOJI_GBT27930_B_PGI_DISCHARGING_REQUIREMENT_EVCC:

        break;
    case OPENCHAOJI_GBT27930_B_PGI_DISCHARGING_STATUS_EVCC:

        break;
    case OPENCHAOJI_GBT27930_B_PGI_DISCHARGING_INFO_BASIC_EVCC:

        break;

#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_STATISTICS == CONFIG_YES)
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_STATISTICS == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_STATISTICS_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_statistics_evcc(context->tag
            , &context->running_data.b->statistics.statistics_evcc
            , &msg.msg.statistics_evcc
        );
        if (!context->running_data.b->statistics.statistics_evcc_ok)
        {
            LOG_WARNING("[%d]statistics_evcc_ok", context->tag);
            context->running_data.b->statistics.statistics_evcc_ok = 1;
            changed = true;
        }
        break;
#endif
#endif

    case OPENCHAOJI_GBT27930_B_PGI_PUBLIC_PHASE_ACK_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_phase_ack_evcc(context->tag
            , &context->running_data.b->phase_ack_evcc
            , &msg.msg.phase_ack_evcc
        );
        if (!context->running_data.b->phase_ack_evcc_ok)
        {
            LOG_WARNING("[%d]phase_ack_evcc_ok", context->tag);
            context->running_data.b->phase_ack_evcc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_PUBLIC_STOP_INFO_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_stop_info_evcc(context->tag
            , &context->running_data.b->stop_info_evcc
            , &msg.msg.stop_info_evcc
        );
        if (!context->running_data.b->stop_info_evcc_ok)
        {
            LOG_WARNING("[%d]stop_info_evcc_ok", context->tag);
            context->running_data.b->stop_info_evcc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_PUBLIC_RELAY_STATUS_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_relay_status_evcc(context->tag
            , &context->running_data.b->relay_status_evcc
            , &msg.msg.relay_status_evcc
        );
        if (!context->running_data.b->relay_status_evcc_ok)
        {
            LOG_WARNING("[%d]relay_status_evcc_ok", context->tag);
            context->running_data.b->relay_status_evcc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_PUBLIC_LATCHING_STATUS_EVCC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_latching_status_evcc(context->tag
            , &context->running_data.b->latchging_status_evcc
            , &msg.msg.latching_status_evcc
        );
        if (!context->running_data.b->latchging_status_evcc_ok)
        {
            LOG_WARNING("[%d]latchging_status_evcc_ok", context->tag);
            context->running_data.b->latchging_status_evcc_ok = 1;
            changed = true;
        }
        break;
    default:
        LOG_ERR("[%d]Unknown PID[%02X]", context->tag, recv_data->recv_data.data[0]);
        goto PARSE_FAILED;
    }

    // 接收数据发生变化必须打出完整报文, 打印级别是INFO则把所有报文打印出来
    if ((changed) || ((OpenChaoJi_debug_get_log_level() & DBGL_INFO) != 0))
    {
        if ((msg.pid == OPENCHAOJI_GBT27930_B_PGI_PUBLIC_LATCHING_STATUS_EVCC)
        || (msg.pid == OPENCHAOJI_GBT27930_B_PGI_PUBLIC_RELAY_STATUS_EVCC)
        )
        {
            if (!changed && !s_gbt_b_public_debug_enable)
            {
                return 0;
            }
        }

        OpenChaoJi_gbt27930_b_msg_log(&msg);
        if ((OpenChaoJi_debug_get_log_level() & DBGL_INFO) != 0)
        {
            LOG_DATA_CHANGE("<-[%02X][%d]", msg.pid, recv_data->recv_data.len);
            LOG_DATA_BUFF_CHANGE(recv_data->recv_data.data, recv_data->recv_data.len);
        }
    }

	return 0;

PARSE_FAILED:
    LOG_ERR("[%d]Invalid MsgFromEvcc", context->tag);
    LOG_BUFF_ERR(recv_data->recv_data.data, recv_data->recv_data.len);
    return -1;
}

#endif
